/*
 * @(#)OctGL.c
 *
 * Copyright 2023 - 2024  David A. Bagley, bagleyd AT verizon.net
 *
 * 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 the author not be
 * used in advertising or publicity pertaining to distribution of the
 * software without specific, written prior permission.
 *
 * This program is distributed in the hope that it will be "useful",
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 */

#ifdef HAVE_OPENGL

/* Methods file for OctGL */

#include "OctP.h"
#include "OctGLP.h"

#define glTranslate(x,y,z) glTranslatef((float) x, (float) y, (float) z)

static float front_shininess[] =
{60.0};
static float front_specular[] =
{(float) 0.7, (float) 0.7, (float) 0.7, 1.0};
static float ambient[] =
{0.0, 0.0, 0.0, 1.0};
static float diffuse[] =
{1.0, 1.0, 1.0, 1.0};
static float position0[] =
{1.0, 0.0, 0.0, 0.0};
static float position1[] =
{0.0, 0.0, 1.0, 0.0};
static float position2[] =
{-1.0, 0.0, 0.0, 0.0};
static float position3[] =
{0.0, 0.0, -1.0, 0.0};
static float position4[] =
{0.0, 1.0, 0.0, 0.0};
static float position5[] =
{0.0, -1.0, 0.0, 0.0};
static float lmodel_ambient[] =
{0.5, 0.5, 0.5, 1.0};
static float lmodel_twoside[] =
{GL_TRUE};

static float face_material[MAX_FACES + 2][4] =
{{1.0, 1.0, 1.0, 1.0},
{1.0, 1.0, 1.0, 1.0},
{1.0, 1.0, 1.0, 1.0},
{1.0, 1.0, 1.0, 1.0},
{1.0, 1.0, 1.0, 1.0},
{1.0, 1.0, 1.0, 1.0},
{1.0, 1.0, 1.0, 1.0},
{1.0, 1.0, 1.0, 1.0},
{0.0, 0.0, 0.0, 1.0},
{0.0, 0.0, 0.0, 1.0}};

/* Blue Red Yellow Green */
/*-
 * Color labels mapping:
 * =====================
 *
 *  RED (0) (at top not visible)
 *             1Y 	 
 *           --+--
 *        ---0/0\0---
 * -1Z ---1 2/1 2\1 2--- 1X
 *    + 3   /3    \3    +
 *    |MAGE/       \BLUE|
 *    |NTA/  WHITE  \(1)|
 *    |(3)/   (2)    \  |
 *    | /             \ |
 *    |/               \|
 *    +-----------------+
 * -1X --   ORANGE    -- 1Z
 *       --   (4) 3 --
 *         -- 2 1 --
 *           --0--
 *             +
 *            -1Y
 * Not visible
 * YELLOW (7)  PINK (2) 
 *     GREEN (6)
 */

static Boolean madeCurrent = False;

#ifdef WINVER
static HGLRC hRC = NULL;
#else
static GLXContext *glXContext = (GLXContext *) NULL;
static Boolean setValuesPuzzleGL(Widget current, Widget request, Widget renew);
static void resizePuzzleGL(OctGLWidget w);
static void initializePuzzleGL(Widget request, Widget renew);
static void exposePuzzleGL(Widget renew, XEvent *event, Region region);
static void movePuzzleGLTl(OctGLWidget w,
	XEvent *event, char **args, int nArgs);
static void movePuzzleGLTop(OctGLWidget w,
	XEvent *event, char **args, int nArgs);
static void movePuzzleGLTr(OctGLWidget w,
	XEvent *event, char **args, int nArgs);
static void movePuzzleGLLeft(OctGLWidget w,
	XEvent *event, char **args, int nArgs);
static void movePuzzleGLRight(OctGLWidget w,
	XEvent *event, char **args, int nArgs);
static void movePuzzleGLBl(OctGLWidget w,
	XEvent *event, char **args, int nArgs);
static void movePuzzleGLBottom(OctGLWidget w,
	XEvent *event, char **args, int nArgs);
static void movePuzzleGLBr(OctGLWidget w,
	XEvent *event, char **args, int nArgs);

static char translationsGL[] =
"<KeyPress>q: Quit()\n\
 Ctrl<KeyPress>C: Quit()\n\
 <KeyPress>osfCancel: Hide()\n\
 <KeyPress>Escape: Hide()\n\
 <KeyPress>osfEscape: Hide()\n\
 Ctrl<KeyPress>[: Hide()\n\
 <KeyPress>0x1B: Hide()\n\
 <KeyPress>0x2E: Speed()\n\
 <KeyPress>0x3E: Speed()\n\
 <KeyPress>0x3C: Slow()\n\
 <KeyPress>0x2C: Slow()\n\
 Shift<KeyPress>2: Sound()\n\
 <KeyPress>F11: MoveCcw()\n\
 <KeyPress>KP_Divide: MoveCcw()\n\
 <KeyPress>R5: MoveCcw()\n\
 <KeyPress>Home: MoveTl()\n\
 <KeyPress>KP_7: MoveTl()\n\
 <KeyPress>R7: MoveTl()\n\
 <KeyPress>Up: MoveTop()\n\
 <KeyPress>osfUp: MoveTop()\n\
 <KeyPress>KP_Up: MoveTop()\n\
 <KeyPress>KP_8: MoveTop()\n\
 <KeyPress>R8: MoveTop()\n\
 <KeyPress>Prior: MoveTr()\n\
 <KeyPress>KP_9: MoveTr()\n\
 <KeyPress>R9: MoveTr()\n\
 <KeyPress>Left: MoveLeft()\n\
 <KeyPress>osfLeft: MoveLeft()\n\
 <KeyPress>KP_Left: MoveLeft()\n\
 <KeyPress>KP_4: MoveLeft()\n\
 <KeyPress>R10: MoveLeft()\n\
 <KeyPress>F12: MoveCw()\n\
 <KeyPress>Begin: MoveCw()\n\
 <KeyPress>KP_5: MoveCw()\n\
 <KeyPress>R11: MoveCw()\n\
 <KeyPress>Right: MoveRight()\n\
 <KeyPress>osfRight: MoveRight()\n\
 <KeyPress>KP_Right: MoveRight()\n\
 <KeyPress>KP_6: MoveRight()\n\
 <KeyPress>R12: MoveRight()\n\
 <KeyPress>End: MoveBl()\n\
 <KeyPress>KP_1: MoveBl()\n\
 <KeyPress>R13: MoveBl()\n\
 <KeyPress>Down: MoveBottom()\n\
 <KeyPress>osfDown: MoveBottom()\n\
 <KeyPress>KP_Down: MoveBottom()\n\
 <KeyPress>KP_2: MoveBottom()\n\
 <KeyPress>R14: MoveBottom()\n\
 <KeyPress>Next: MoveBr()\n\
 <KeyPress>KP_3: MoveBr()\n\
 <KeyPress>R15: MoveBr()\n\
 <Btn1Down>: Select()\n\
 <Btn1Up>: Release()\n\
 <Btn2Down>: PracticeMaybe()\n\
 <Btn2Down>(2+): Practice2()\n\
 <Btn3Down>: RandomizeMaybe()\n\
 <Btn3Down>(2+): Randomize2()\n\
 <Btn4Down>: MoveTop()\n\
 <Btn5Down>: MoveBottom()\n\
 <KeyPress>g: Get()\n\
 <KeyPress>w: Write()\n\
 <KeyPress>u: Undo()\n\
 <KeyPress>r: Redo()\n\
 <KeyPress>c: Clear()\n\
 <KeyPress>z: Randomize()\n\
 <KeyPress>s: Solve()\n\
 <KeyPress>f: Find()\n\
 <KeyPress>p: Practice()\n\
 <KeyPress>i: Increment()\n\
 <KeyPress>d: Decrement()\n\
 <KeyPress>o: Orientize()\n\
 <KeyPress>3: Period3()\n\
 <KeyPress>4: Period4()\n\
 <KeyPress>b: Both()\n\
 <KeyPress>y: Sticky()\n\
 <KeyPress>v: View()\n\
 <EnterWindow>: Enter()\n\
 <LeaveWindow>: Leave()";

static XtActionsRec actionsListGL[] =
{
	{(char *) "Quit", (XtActionProc) quitPuzzle},
	{(char *) "Hide", (XtActionProc) hidePuzzle},
	{(char *) "MoveCcw", (XtActionProc) movePuzzleCcw},
	{(char *) "MoveTl", (XtActionProc) movePuzzleGLTl},
	{(char *) "MoveTop", (XtActionProc) movePuzzleGLTop},
	{(char *) "MoveTr", (XtActionProc) movePuzzleGLTr},
	{(char *) "MoveLeft", (XtActionProc) movePuzzleGLLeft},
	{(char *) "MoveCw", (XtActionProc) movePuzzleCw},
	{(char *) "MoveBr", (XtActionProc) movePuzzleGLBr},
	{(char *) "MoveRight", (XtActionProc) movePuzzleGLRight},
	{(char *) "MoveBl", (XtActionProc) movePuzzleGLBl},
	{(char *) "MoveBottom", (XtActionProc) movePuzzleGLBottom},
	{(char *) "MoveBr", (XtActionProc) movePuzzleGLBr},
	{(char *) "Select", (XtActionProc) selectPuzzle},
	{(char *) "Release", (XtActionProc) releasePuzzle},
	{(char *) "PracticeMaybe", (XtActionProc) practicePuzzleWithQuery},
	{(char *) "Practice2", (XtActionProc) practicePuzzleWithDoubleClick},
	{(char *) "RandomizeMaybe", (XtActionProc) randomizePuzzleWithQuery},
	{(char *) "Randomize2", (XtActionProc) randomizePuzzleWithDoubleClick},
	{(char *) "Get", (XtActionProc) getPuzzle},
	{(char *) "Write", (XtActionProc) writePuzzle},
	{(char *) "Undo", (XtActionProc) undoPuzzle},
	{(char *) "Redo", (XtActionProc) redoPuzzle},
	{(char *) "Clear", (XtActionProc) clearPuzzle},
	{(char *) "Randomize", (XtActionProc) randomizePuzzle},
	{(char *) "Solve", (XtActionProc) solvePuzzle},
	{(char *) "Find", (XtActionProc) findPuzzle},
	{(char *) "Practice", (XtActionProc) practicePuzzle},
	{(char *) "Increment", (XtActionProc) incrementPuzzle},
	{(char *) "Decrement", (XtActionProc) decrementPuzzle},
	{(char *) "Orientize", (XtActionProc) orientizePuzzle},
	{(char *) "Period3", (XtActionProc) period3ModePuzzle},
	{(char *) "Period4", (XtActionProc) period4ModePuzzle},
	{(char *) "Both", (XtActionProc) bothModePuzzle},
	{(char *) "Sticky", (XtActionProc) stickyModePuzzle},
	{(char *) "View", (XtActionProc) viewPuzzle},
	{(char *) "Speed", (XtActionProc) speedUpPuzzle},
	{(char *) "Slow", (XtActionProc) slowDownPuzzle},
	{(char *) "Sound", (XtActionProc) toggleSoundPuzzle},
	{(char *) "Enter", (XtActionProc) enterPuzzle},
	{(char *) "Leave", (XtActionProc) leavePuzzle}
};

static XtResource resourcesGL[] =
{
	{XtNwidth, XtCWidth, XtRDimension, sizeof (Dimension),
	 XtOffset(OctWidget, core.width),
	 XtRString, (caddr_t) "300"},
	{XtNheight, XtCHeight, XtRDimension, sizeof (Dimension),
	 XtOffset(OctWidget, core.height),
	 XtRString, (caddr_t) "400"},
	{XtNmono, XtCMono, XtRBoolean, sizeof (Boolean),
	 XtOffset(OctWidget, oct.mono),
	 XtRString, (caddr_t) "FALSE"},
	{XtNreverseVideo, XtCReverseVideo, XtRBoolean, sizeof (Boolean),
	 XtOffset(OctWidget, oct.reverse),
	 XtRString, (caddr_t) "FALSE"},
	{XtNforeground, XtCForeground, XtRPixel, sizeof (Pixel),
	 XtOffset(OctWidget, oct.foreground),
	 XtRString, (caddr_t) XtDefaultForeground},
	{XtNbackground, XtCBackground, XtRPixel, sizeof (Pixel),
	 XtOffset(OctWidget, oct.background),
	 XtRString, (caddr_t) "#AEB2C3" /*XtDefaultBackground*/},
	{XtNframeColor, XtCColor, XtRPixel, sizeof (Pixel),
	 XtOffset(OctWidget, oct.frameColor),
	 XtRString, (caddr_t) "Cyan" /*XtDefaultForeground*/},
	{XtNfaceColor0, XtCLabel, XtRString, sizeof (String),
	 XtOffset(OctWidget, oct.faceName[0]),
	 XtRString, (caddr_t) "Red"},
	{XtNfaceColor1, XtCLabel, XtRString, sizeof (String),
	 XtOffset(OctWidget, oct.faceName[1]),
	 XtRString, (caddr_t) "Blue"},
	{XtNfaceColor2, XtCLabel, XtRString, sizeof (String),
	 XtOffset(OctWidget, oct.faceName[2]),
	 XtRString, (caddr_t) "White"},
	{XtNfaceColor3, XtCLabel, XtRString, sizeof (String),
	 XtOffset(OctWidget, oct.faceName[3]),
	 XtRString, (caddr_t) "Magenta"},
	{XtNfaceColor4, XtCLabel, XtRString, sizeof (String),
	 XtOffset(OctWidget, oct.faceName[4]),
	 XtRString, (caddr_t) "Orange"},
	{XtNfaceColor5, XtCLabel, XtRString, sizeof (String),
	 XtOffset(OctWidget, oct.faceName[5]),
	 XtRString, (caddr_t) "Pink"},
	{XtNfaceColor6, XtCLabel, XtRString, sizeof (String),
	 XtOffset(OctWidget, oct.faceName[6]),
	 XtRString, (caddr_t) "Green"},
	{XtNfaceColor7, XtCLabel, XtRString, sizeof (String),
	 XtOffset(OctWidget, oct.faceName[7]),
	 XtRString, (caddr_t) "Yellow"},
	{XtNpieceBorder, XtCColor, XtRPixel, sizeof (Pixel),
	 XtOffset(OctWidget, oct.borderColor),
	 XtRString, (caddr_t) "gray25" /*XtDefaultForeground*/},
	{XtNdelay, XtCDelay, XtRInt, sizeof (int),
	 XtOffset(OctWidget, oct.delay),
	 XtRString, (caddr_t) "10"},
	{XtNsound, XtCSound, XtRBoolean, sizeof (Boolean),
	 XtOffset(OctWidget, oct.sound),
	 XtRString, (caddr_t) "FALSE"},
	{XtNmoveSound, XtCMoveSound, XtRString, sizeof (String),
	 XtOffset(OctWidget, oct.moveSound),
	 XtRString, (caddr_t) MOVESOUND},
	{XtNfont, XtCFont, XtRString, sizeof (String),
	 XtOffset(OctWidget, oct.font),
	 XtRString, (caddr_t) "9x15bold"},
	{XtNview, XtCView, XtRInt, sizeof (int),
	 XtOffset(OctWidget, oct.view),
	 XtRString, (caddr_t) "1"},
	{XtNsize, XtCSize, XtRInt, sizeof (int),
	 XtOffset(OctWidget, oct.size),
	 XtRString, (caddr_t) "3"}, /*DEFAULT_FACETS */
	{XtNsticky, XtCSticky, XtRBoolean, sizeof (Boolean),
	 XtOffset(OctWidget, oct.sticky),
	 XtRString, (caddr_t) "FALSE"}, /* DEFAULT_STICKY */
	{XtNmode, XtCMode, XtRInt, sizeof (int),
	 XtOffset(OctWidget, oct.mode),
	 XtRString, (caddr_t) "4"}, /*DEFAULT_MODE */
	{XtNorient, XtCOrient, XtRBoolean, sizeof (Boolean),
	 XtOffset(OctWidget, oct.orient),
	 XtRString, (caddr_t) "FALSE"},	/* DEFAULT_ORIENT */
	{XtNpractice, XtCPractice, XtRBoolean, sizeof (Boolean),
	 XtOffset(OctWidget, oct.practice),
	 XtRString, (caddr_t) "TRUE"}, /* DEFAULT_PRACTICE */
	{XtNuserName, XtCUserName, XtRString, sizeof (String),
	 XtOffset(OctWidget, oct.userName),
	 XtRString, (caddr_t) ""},
	{XtNscoreFile, XtCScoreFile, XtRString, sizeof (String),
	 XtOffset(OctWidget, oct.scoreFile),
	 XtRString, (caddr_t) ""},
	{XtNscoreOnly, XtCBoolean, XtRBoolean, sizeof (Boolean),
	 XtOffset(OctWidget, oct.scoreOnly),
	 XtRString, (caddr_t) "FALSE"},
	{XtNversionOnly, XtCBoolean, XtRBoolean, sizeof (Boolean),
	 XtOffset(OctWidget, oct.versionOnly),
	 XtRString, (caddr_t) "FALSE"},
	{XtNmenu, XtCMenu, XtRInt, sizeof (int),
	 XtOffset(OctWidget, oct.menu),
	 XtRString, (caddr_t) "999"}, /* ACTION_IGNORE */
	{XtNstart, XtCBoolean, XtRBoolean, sizeof (Boolean),
	 XtOffset(OctWidget, oct.started),
	 XtRString, (caddr_t) "FALSE"},
	{XtNcheat, XtCBoolean, XtRBoolean, sizeof (Boolean),
	 XtOffset(OctWidget, oct.cheat),
	 XtRString, (caddr_t) "FALSE"},
	{XtNface, XtCFace, XtRInt, sizeof (int),
	 XtOffset(OctWidget, oct.currentFace),
	 XtRString, (caddr_t) "-1"},
	{XtNpos, XtCPos, XtRInt, sizeof (int),
	 XtOffset(OctWidget, oct.currentPosition),
	 XtRString, (caddr_t) "-1"},
	{XtNdirection, XtCDirection, XtRInt, sizeof (int),
	 XtOffset(OctWidget, oct.currentDirection),
	 XtRString, (caddr_t) "-1"},
	{XtNstyle, XtCStyle, XtRInt, sizeof (int),
	 XtOffset(OctWidget, oct.currentStyle),
	 XtRString, (caddr_t) "-1"},
	{XtNcontrol, XtCControl, XtRInt, sizeof (int),
	 XtOffset(OctWidget, oct.currentControl),
	 XtRString, (caddr_t) "0"},
	{XtNfast, XtCFast, XtRInt, sizeof (int),
	 XtOffset(OctWidget, oct.currentFast),
	 XtRString, (caddr_t) "1"},
	{XtNpixmapSize, XtCPixmapSize, XtRInt, sizeof (int),
	 XtOffset(OctWidget, oct.pixmapSize),
	 XtRString, (caddr_t) "64"},
	{XtNselectCallback, XtCCallback, XtRCallback, sizeof (caddr_t),
	 XtOffset(OctWidget, oct.select),
	 XtRCallback, (caddr_t) NULL}
};

OctGLClassRec octGLClassRec =
{
	{
		(WidgetClass) & octClassRec,	/* superclass */
		(char *) "OctGL",	/* class name */
		sizeof (OctGLRec),	/* widget size */
		NULL,		/* class initialize */
		NULL,		/* class part initialize */
		FALSE,		/* class inited */
		(XtInitProc) initializePuzzleGL,	/* initialize */
		NULL,		/* initialize hook */
		XtInheritRealize,	/* realize */
		actionsListGL,	/* actions */
		XtNumber(actionsListGL),	/* num actions */
		resourcesGL,	/* resources */
		XtNumber(resourcesGL),	/* num resources */
		NULLQUARK,	/* xrm class */
		TRUE,		/* compress motion */
		TRUE,		/* compress exposure */
		TRUE,		/* compress enterleave */
		TRUE,		/* visible interest */
		NULL,		/* destroy */
		(XtWidgetProc) resizePuzzleGL,	/* resize */
		(XtExposeProc) exposePuzzleGL,	/* expose */
		(XtSetValuesFunc) setValuesPuzzleGL,	/* set values */
		NULL,		/* set values hook */
		XtInheritSetValuesAlmost,	/* set values almost */
		NULL,		/* get values hook */
		XtInheritAcceptFocus,	/* accept focus */
		XtVersion,	/* version */
		NULL,		/* callback private */
		translationsGL,	/* tm table */
		NULL,		/* query geometry */
		NULL,		/* display accelerator */
		NULL		/* extension */
	},
	{
		0		/* ignore */
	},
	{
		0		/* ignore */
	}
};

WidgetClass octGLWidgetClass = (WidgetClass) & octGLClassRec;
#endif

static void
pickColor(OctGLWidget w, int c, int mono, float *material)
{
#ifdef WINVER
	struct tagColor {
		int red, green, blue;
	} color;
#define MAX_INTENSITY 0xFF
#else
	XColor color;
#define MAX_INTENSITY 0xFFFF
#endif

	switch (c) {
	case TOP_FACE:
	case RIGHT_FACE:
	case BOTTOM_FACE:
	case LEFT_FACE:
	case TOP_BACK:
	case RIGHT_BACK:
	case BOTTOM_BACK:
	case LEFT_BACK:
#ifdef WINVER
		color.red = GetRValue(w->oct.faceGC[c]);
		color.green = GetGValue(w->oct.faceGC[c]);
		color.blue = GetBValue(w->oct.faceGC[c]);
#else
		color.pixel = w->oct.faceColor[c];
		XQueryColor(XtDisplay(w), DefaultColormapOfScreen(XtScreen(w)),
			&color);
#endif
		break;
	case BORDER_FACE:
#ifdef WINVER
		color.red = GetRValue(w->oct.borderGC);
		color.green = GetGValue(w->oct.borderGC);
		color.blue = GetBValue(w->oct.borderGC);
#else
		color.pixel = w->oct.borderColor;
		XQueryColor(XtDisplay(w), DefaultColormapOfScreen(XtScreen(w)),
			&color);
#endif
		break;
	case NO_FACE:
	default:
#ifdef WINVER
		color.red = GetRValue(w->oct.inverseGC);
		color.green = GetGValue(w->oct.inverseGC);
		color.blue = GetBValue(w->oct.inverseGC);
#else
		color.pixel = w->oct.background;
		XQueryColor(XtDisplay(w), DefaultColormapOfScreen(XtScreen(w)),
			&color);
#endif
		break;
	}
#ifdef DEBUG
	(void) printf("%d: i%d %d %d\n", c, color.red, color.green, color.blue);
#endif
	if (mono) {
		/* really GrayScale */
		float intensity = (float) (0.3 * color.red +
			0.59 * color.green + 0.11 * color.blue);
#ifdef DEBUG
		(void) printf("m%g\n", intensity);
#endif
		material[0] = (float) intensity / MAX_INTENSITY;
		material[1] = material[0];
		material[2] = material[0];
	} else {
#if 1	/* Hack: Orange and Pink were getting washed out */
		if (c < BORDER_FACE && ((color.red != 0 && color.red != MAX_INTENSITY)
				|| (color.green != 0 && color.green != MAX_INTENSITY)
				|| (color.blue != 0 && color.blue != MAX_INTENSITY))) {

			material[0] = (GLfloat) color.red / (2 * MAX_INTENSITY);
			material[1] = (GLfloat) color.green / (2 * MAX_INTENSITY);
			material[2] = (GLfloat) color.blue / (2 * MAX_INTENSITY);
		} else
#endif
		{
			material[0] = (GLfloat) color.red / MAX_INTENSITY;
			material[1] = (GLfloat) color.green / MAX_INTENSITY;
			material[2] = (GLfloat) color.blue / MAX_INTENSITY;
		}
	}
#ifdef DEBUG
	(void) printf("%d: f%g %g %g\n", c, material[0], material[1], material[2]);
#endif
}

typedef float Matrix[3][3];
typedef float Vector[3];

static void
matrixMatrix(Matrix a, Matrix b, Matrix x)
{
	int i, j;

	for (i = 0; i < 3; i++) {
		for (j = 0; j < 3; j++) {
			x[i][j] = a[i][0] * b[0][j] +
				a[i][1] * b[1][j] +
				a[i][2] * b[2][j];
		}
	}
}

static void
matrixVector(Matrix a, Vector v, Vector x)
{
	int i;

	for (i = 0; i < 3; i++) {
		x[i] = a[i][0] * v[0] +
			a[i][1] * v[1] +
			a[i][2] * v[2];
	}
}

static void
setMatrix(float theta, float x, float y, float z, Matrix a)
{
	float s = (float) sin(theta * M_PI / 180.0);
	float c = (float) cos(theta * M_PI / 180.0);

	if (x != 0.0 && y == 0.0 && z == 0.0) {
		a[0][0] = 1.0, a[0][1] = 0.0; a[0][2] = 0.0;
		a[1][0] = 0.0, a[1][1] = c; a[1][2] = -s;
		a[2][0] = 0.0, a[2][1] = s; a[2][2] = c;
	} else if (y != 0.0 && x == 0.0 && z == 0.0) {
		a[0][0] = c, a[0][1] = 0.0; a[0][2] = s;
		a[1][0] = 0.0, a[1][1] = 1.0; a[1][2] = 0.0;
		a[2][0] = -s, a[2][1] = 0.0; a[2][2] = c;
	} else if (z != 0.0 && x == 0.0 && y == 0.0) {
		a[0][0] = c, a[0][1] = -s; a[0][2] = 0.0;
		a[1][0] = s, a[1][1] = c; a[1][2] = 0.0;
		a[2][0] = 0.0, a[2][1] = 0.0; a[2][2] = 1.0;
	}
}

static void
drawStickerlessTetra(void)
{
	glPushMatrix();
	glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE,
		face_material[BORDER_FACE]);
	glBegin(GL_TRIANGLES);
	/* OPP GREEN FRONT */
	glNormal3f(-1.0, 1.0, 1.0);
	glVertex3f(-FACET_TETRA, FACET_LENGTH, FACET_LENGTH);
	glVertex3f(-FACET_LENGTH, FACET_LENGTH, FACET_TETRA);
	glVertex3f(-FACET_LENGTH, FACET_TETRA, FACET_LENGTH);
	/* OPP RED LEFT */
	glNormal3f(-1.0, -1.0, -1.0);
	glVertex3f(-FACET_LENGTH, -FACET_TETRA, -FACET_LENGTH);
	glVertex3f(-FACET_TETRA, -FACET_LENGTH, -FACET_LENGTH);
	glVertex3f(-FACET_LENGTH, -FACET_LENGTH, -FACET_TETRA);
	/* OPP YELLOW TOP */
	glNormal3f(1.0, 1.0, -1.0);
	glVertex3f(FACET_TETRA, FACET_LENGTH, -FACET_LENGTH);
	glVertex3f(FACET_LENGTH, FACET_LENGTH, -FACET_TETRA);
	glVertex3f(FACET_LENGTH, FACET_TETRA, -FACET_LENGTH);
	/* OPP BLUE RIGHT */
	glNormal3f(1.0, -1.0, 1.0);
	glVertex3f(FACET_LENGTH, -FACET_TETRA, FACET_LENGTH);
	glVertex3f(FACET_LENGTH, -FACET_LENGTH, FACET_TETRA);
	glVertex3f(FACET_TETRA, -FACET_LENGTH, FACET_LENGTH);

	/* TOP_FACE */
	glNormal3f(-1.0, 1.0, -1.0);
	glVertex3f(-FACET_LENGTH, -FACET_TETRA, -FACET_LENGTH);
	glVertex3f(-FACET_LENGTH, FACET_LENGTH, FACET_TETRA);
	glVertex3f(FACET_TETRA, FACET_LENGTH, -FACET_LENGTH);
	/* RIGHT_FACE */
	glNormal3f(1.0, 1.0, 1.0);
	glVertex3f(FACET_LENGTH, FACET_LENGTH, -FACET_TETRA);
	glVertex3f(-FACET_TETRA, FACET_LENGTH, FACET_LENGTH);
	glVertex3f(FACET_LENGTH, -FACET_TETRA, FACET_LENGTH);
	/* LEFT_FACE */
	glNormal3f(-1.0, -1.0, 1.0);
	glVertex3f(FACET_TETRA, -FACET_LENGTH, FACET_LENGTH);
	glVertex3f(-FACET_LENGTH, FACET_TETRA, FACET_LENGTH);
	glVertex3f(-FACET_LENGTH, -FACET_LENGTH, -FACET_TETRA);
	/* BOTTOM_FACE */
	glNormal3f(1.0, -1.0, -1.0);
	glVertex3f(FACET_LENGTH, FACET_TETRA, -FACET_LENGTH);
	glVertex3f(FACET_LENGTH, -FACET_LENGTH, FACET_TETRA);
	glVertex3f(-FACET_TETRA, -FACET_LENGTH, -FACET_LENGTH);
	glEnd();

	glBegin(GL_QUADS);
	/* LEFT BAR */
	glNormal3f(-1.0, 0.0, 0.0);
	glVertex3f(-FACET_LENGTH, -FACET_TETRA, -FACET_LENGTH);
	glVertex3f(-FACET_LENGTH, -FACET_LENGTH, -FACET_TETRA);
	glVertex3f(-FACET_LENGTH, FACET_TETRA, FACET_LENGTH);
	glVertex3f(-FACET_LENGTH, FACET_LENGTH, FACET_TETRA);
	/* TOP BAR */
	glNormal3f(1.0, 0.0, 0.0);
	glVertex3f(FACET_LENGTH, FACET_LENGTH, -FACET_TETRA);
	glVertex3f(FACET_TETRA, FACET_LENGTH, -FACET_LENGTH);
	glVertex3f(-FACET_LENGTH, FACET_LENGTH, FACET_TETRA);
	glVertex3f(-FACET_TETRA, FACET_LENGTH, FACET_LENGTH);
	/* RIGHT BAR */
	glNormal3f(0.0, 0.0, 1.0);
	glVertex3f(FACET_TETRA, -FACET_LENGTH, FACET_LENGTH);
	glVertex3f(FACET_LENGTH, -FACET_TETRA, FACET_LENGTH);
	glVertex3f(-FACET_TETRA, FACET_LENGTH, FACET_LENGTH);
	glVertex3f(-FACET_LENGTH, FACET_TETRA, FACET_LENGTH);
	/* FAR LEFT BAR */
	glNormal3f(0.0, 0.0, -1.0);
	glVertex3f(-FACET_TETRA, -FACET_LENGTH, -FACET_LENGTH);
	glVertex3f(-FACET_LENGTH, -FACET_TETRA, -FACET_LENGTH);
	glVertex3f(FACET_TETRA, FACET_LENGTH, -FACET_LENGTH);
	glVertex3f(FACET_LENGTH, FACET_TETRA, -FACET_LENGTH);
	/* FAR RIGHT BAR */
	glNormal3f(1.0, 0.0, 0.0);
	glVertex3f(FACET_LENGTH, FACET_TETRA, -FACET_LENGTH);
	glVertex3f(FACET_LENGTH, FACET_LENGTH, -FACET_TETRA);
	glVertex3f(FACET_LENGTH, -FACET_TETRA, FACET_LENGTH);
	glVertex3f(FACET_LENGTH, -FACET_LENGTH, FACET_TETRA);
	/* BOTTOM BAR */
	glNormal3f(0.0, -1.0, 0.0);
	glVertex3f(-FACET_LENGTH, -FACET_LENGTH, -FACET_TETRA);
	glVertex3f(-FACET_TETRA, -FACET_LENGTH, -FACET_LENGTH);
	glVertex3f(FACET_LENGTH, -FACET_LENGTH, FACET_TETRA);
	glVertex3f(FACET_TETRA, -FACET_LENGTH, FACET_LENGTH);
	glEnd();
	glPopMatrix();
}

static void
drawStickerlessInvTetra(void)
{
	glPushMatrix();
	glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE,
		face_material[BORDER_FACE]);
	glBegin(GL_TRIANGLES);
	/* OPP GREEN BACK */
	glNormal3f(1.0, -1.0, -1.0);
	glVertex3f(FACET_LENGTH, -FACET_TETRA, -FACET_LENGTH);
	glVertex3f(FACET_LENGTH, -FACET_LENGTH, -FACET_TETRA);
	glVertex3f(FACET_TETRA, -FACET_LENGTH, -FACET_LENGTH);
	/* OPP RED RIGHT */
	glNormal3f(1.0, 1.0, 1.0);
	glVertex3f(FACET_LENGTH, FACET_LENGTH, FACET_TETRA);
	glVertex3f(FACET_TETRA, FACET_LENGTH, FACET_LENGTH);
	glVertex3f(FACET_LENGTH, FACET_TETRA, FACET_LENGTH);
	/* OPP YELLOW BOTTOM */
	glNormal3f(-1.0, -1.0, 1.0);
	glVertex3f(-FACET_LENGTH, -FACET_TETRA, FACET_LENGTH);
	glVertex3f(-FACET_LENGTH, -FACET_LENGTH, FACET_TETRA);
	glVertex3f(-FACET_TETRA, -FACET_LENGTH, FACET_LENGTH);
	/* OPP BLUE LEFT */
	glNormal3f(-1.0, 1.0, -1.0);
	glVertex3f(-FACET_TETRA, FACET_LENGTH, -FACET_LENGTH);
	glVertex3f(-FACET_LENGTH, FACET_LENGTH, -FACET_TETRA);
	glVertex3f(-FACET_LENGTH, FACET_TETRA, -FACET_LENGTH);

	/* BOTTOM_FACE */
	glNormal3f(1.0, -1.0, 1.0);
	glVertex3f(-FACET_TETRA, -FACET_LENGTH, FACET_LENGTH);
	glVertex3f(FACET_LENGTH, -FACET_LENGTH, -FACET_TETRA);
	glVertex3f(FACET_LENGTH, FACET_TETRA, FACET_LENGTH);
	/* LEFT_FACE */
	glNormal3f(-1.0, -1.0, -1.0);
	glVertex3f(-FACET_LENGTH, FACET_TETRA, -FACET_LENGTH);
	glVertex3f(FACET_TETRA, -FACET_LENGTH, -FACET_LENGTH);
	glVertex3f(-FACET_LENGTH, -FACET_LENGTH, FACET_TETRA);
	/* RIGHT_FACE */
	glNormal3f(1.0, 1.0, -1.0);
	glVertex3f(FACET_LENGTH, FACET_LENGTH, FACET_TETRA);
	glVertex3f(FACET_LENGTH, -FACET_TETRA, -FACET_LENGTH);
	glVertex3f(-FACET_TETRA, FACET_LENGTH, -FACET_LENGTH);
	/* TOP_FACE */
	glNormal3f(-1.0, 1.0, 1.0);
	glVertex3f(FACET_TETRA, FACET_LENGTH, FACET_LENGTH);
	glVertex3f(-FACET_LENGTH, FACET_LENGTH, -FACET_TETRA);
	glVertex3f(-FACET_LENGTH, -FACET_TETRA, FACET_LENGTH);
	glEnd();

	glBegin(GL_QUADS);
	/* RIGHT BAR */
	glNormal3f(1.0, 0.0, 0.0);
	glVertex3f(FACET_LENGTH, -FACET_LENGTH, -FACET_TETRA);
	glVertex3f(FACET_LENGTH, -FACET_TETRA, -FACET_LENGTH);
	glVertex3f(FACET_LENGTH, FACET_LENGTH, FACET_TETRA);
	glVertex3f(FACET_LENGTH, FACET_TETRA, FACET_LENGTH);
	/* BOTTOM BAR */
	glNormal3f(-1.0, 0.0, 0.0);
	glVertex3f(FACET_TETRA, -FACET_LENGTH, -FACET_LENGTH);
	glVertex3f(FACET_LENGTH, -FACET_LENGTH, -FACET_TETRA);
	glVertex3f(-FACET_TETRA, -FACET_LENGTH, FACET_LENGTH);
	glVertex3f(-FACET_LENGTH, -FACET_LENGTH, FACET_TETRA);
	/* LEFT BAR */
	glNormal3f(0.0, 0.0, -1.0);
	glVertex3f(FACET_LENGTH, -FACET_TETRA, -FACET_LENGTH);
	glVertex3f(FACET_TETRA, -FACET_LENGTH, -FACET_LENGTH);
	glVertex3f(-FACET_LENGTH, FACET_TETRA, -FACET_LENGTH);
	glVertex3f(-FACET_TETRA, FACET_LENGTH, -FACET_LENGTH);

	/* FAR RIGHT BAR */
	glNormal3f(0.0, 0.0, 1.0);
	glVertex3f(-FACET_LENGTH, -FACET_TETRA, FACET_LENGTH);
	glVertex3f(-FACET_TETRA, -FACET_LENGTH, FACET_LENGTH);
	glVertex3f(FACET_LENGTH, FACET_TETRA, FACET_LENGTH);
	glVertex3f(FACET_TETRA, FACET_LENGTH, FACET_LENGTH);
	/* FAR LEFT BAR */
	glNormal3f(-1.0, 0.0, 0.0);
	glVertex3f(-FACET_LENGTH, FACET_LENGTH, -FACET_TETRA);
	glVertex3f(-FACET_LENGTH, FACET_TETRA, -FACET_LENGTH);
	glVertex3f(-FACET_LENGTH, -FACET_LENGTH, FACET_TETRA);
	glVertex3f(-FACET_LENGTH, -FACET_TETRA, FACET_LENGTH);
	/* TOP BAR */
	glNormal3f(0.0, 1.0, 0.0);
	glVertex3f(-FACET_TETRA, FACET_LENGTH, -FACET_LENGTH);
	glVertex3f(-FACET_LENGTH, FACET_LENGTH, -FACET_TETRA);
	glVertex3f(FACET_TETRA, FACET_LENGTH, FACET_LENGTH);
	glVertex3f(FACET_LENGTH, FACET_LENGTH, FACET_TETRA);
	glEnd();
	glPopMatrix();
}

static void
drawStickerlessOcta(int topFace, int rightFace, int bottomFace, int leftFace,
		int topBack, int rightBack, int bottomBack, int leftBack)
{
	glPushMatrix();
	glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE,
		face_material[BORDER_FACE]);
	glBegin(GL_QUADS);
	if (topFace != NO_POSITION || rightFace != NO_POSITION) {
		glNormal3f(1.0, 1.0, 0.0);
		glVertex3f(CUT, FACET_OCTA, BAR_WIDTH); /* TOP RIGHT BAR */
		glVertex3f(FACET_OCTA, CUT, BAR_WIDTH);
		glVertex3f(FACET_OCTA, CUT, -BAR_WIDTH);
		glVertex3f(CUT, FACET_OCTA, -BAR_WIDTH);
	}
	if (rightFace != NO_POSITION || bottomFace != NO_POSITION) {
		glNormal3f(0.0, 1.0, 1.0);
		glVertex3f(-BAR_WIDTH, CUT, FACET_OCTA); /* TOP FRONT RIGHT BAR */
		glVertex3f(BAR_WIDTH, CUT, FACET_OCTA);
		glVertex3f(BAR_WIDTH, FACET_OCTA, CUT);
		glVertex3f(-BAR_WIDTH, FACET_OCTA, CUT);
	}
	if (bottomFace != NO_POSITION || leftFace != NO_POSITION) {
		glNormal3f(-1.0, 1.0, 0.0);
		glVertex3f(-FACET_OCTA, CUT, BAR_WIDTH); /* TOP FRONT LEFT BAR */
		glVertex3f(-CUT, FACET_OCTA, BAR_WIDTH);
		glVertex3f(-CUT, FACET_OCTA, -BAR_WIDTH);
		glVertex3f(-FACET_OCTA, CUT, -BAR_WIDTH);
	}
	if (topFace != NO_POSITION || leftFace != NO_POSITION) {
		glNormal3f(0.0, 1.0, -1.0);
		glVertex3f(BAR_WIDTH, CUT, -FACET_OCTA); /* TOP LEFT BAR */
		glVertex3f(-BAR_WIDTH, CUT, -FACET_OCTA);
		glVertex3f(-BAR_WIDTH, FACET_OCTA, -CUT);
		glVertex3f(BAR_WIDTH, FACET_OCTA, -CUT);
	}

	if (topFace != NO_POSITION || bottomBack != NO_POSITION) {
		glNormal3f(1.0, 0.0, -1.0);
		glVertex3f(FACET_OCTA, BAR_WIDTH, -CUT); /* BACK BOTTOM BAR */
		glVertex3f(FACET_OCTA, -BAR_WIDTH, -CUT);
		glVertex3f(CUT, -BAR_WIDTH, -FACET_OCTA);
		glVertex3f(CUT, BAR_WIDTH, -FACET_OCTA);
	}
	if (rightFace != NO_POSITION || rightBack != NO_POSITION) {
		glNormal3f(1.0, 0.0, 1.0);
		glVertex3f(FACET_OCTA, -BAR_WIDTH, CUT); /* FAR RIGHT BAR */
		glVertex3f(FACET_OCTA, BAR_WIDTH, CUT);
		glVertex3f(CUT, BAR_WIDTH, FACET_OCTA);
		glVertex3f(CUT, -BAR_WIDTH, FACET_OCTA);
	}
	if (bottomFace != NO_POSITION || topBack != NO_POSITION) {
		glNormal3f(-1.0, 0.0, 1.0);
		glVertex3f(-FACET_OCTA, -BAR_WIDTH, CUT); /* BOTTOM BAR */
		glVertex3f(-CUT, -BAR_WIDTH, FACET_OCTA);
		glVertex3f(-CUT, BAR_WIDTH, FACET_OCTA);
		glVertex3f(-FACET_OCTA, BAR_WIDTH, CUT);
	}
	if (leftFace != NO_POSITION || leftBack != NO_POSITION) {
		glNormal3f(-1.0, 0.0, -1.0);
		glVertex3f(-FACET_OCTA, BAR_WIDTH, -CUT); /* FAR LEFT BAR */
		glVertex3f(-CUT, BAR_WIDTH, -FACET_OCTA);
		glVertex3f(-CUT, -BAR_WIDTH, -FACET_OCTA);
		glVertex3f(-FACET_OCTA, -BAR_WIDTH, -CUT);
	}

	if (rightBack != NO_POSITION || bottomBack != NO_POSITION) {
		glNormal3f(1.0, -1.0, 0.0);
		glVertex3f(FACET_OCTA, -CUT, -BAR_WIDTH); /* BACK RIGHT BAR */
		glVertex3f(FACET_OCTA, -CUT, BAR_WIDTH);
		glVertex3f(CUT, -FACET_OCTA, BAR_WIDTH);
		glVertex3f(CUT, -FACET_OCTA, -BAR_WIDTH);
	}
	if (topBack != NO_POSITION || rightBack != NO_POSITION) {
		glNormal3f(0.0, -1.0, 1.0);
		glVertex3f(-BAR_WIDTH, -CUT, FACET_OCTA); /* BACK UPPER RIGHT BAR */
		glVertex3f(-BAR_WIDTH, -FACET_OCTA, CUT);
		glVertex3f(BAR_WIDTH, -FACET_OCTA, CUT);
		glVertex3f(BAR_WIDTH, -CUT, FACET_OCTA);
	}
	if (topBack != NO_POSITION || leftBack != NO_POSITION) {
		glNormal3f(-1.0, -1.0, 0.0);
		glVertex3f(-CUT, -FACET_OCTA, -BAR_WIDTH); /* BACK UPPER LEFT BAR */
		glVertex3f(-CUT, -FACET_OCTA, BAR_WIDTH);
		glVertex3f(-FACET_OCTA, -CUT, BAR_WIDTH);
		glVertex3f(-FACET_OCTA, -CUT, -BAR_WIDTH);
	}
	if (bottomBack != NO_POSITION || leftBack != NO_POSITION) {
		glNormal3f(0.0, -1.0, -1.0);
		glVertex3f(BAR_WIDTH, -CUT, -FACET_OCTA); /* LEFT BAR */
		glVertex3f(BAR_WIDTH, -FACET_OCTA, -CUT);
		glVertex3f(-BAR_WIDTH, -FACET_OCTA, -CUT);
		glVertex3f(-BAR_WIDTH, -CUT, -FACET_OCTA);
	}
	glEnd();

	/* POINTS */
	if (bottomFace != NO_POSITION || leftFace != NO_POSITION
			|| topBack != NO_POSITION || leftBack != NO_POSITION) {
		glBegin(GL_POLYGON);
		glNormal3f(-1.0, 0.0, 0.0);
		glVertex3f(-FACET_OCTA, -CUT, -BAR_WIDTH); /* LEFT */
		glVertex3f(-FACET_OCTA, -CUT, BAR_WIDTH);
		glVertex3f(-FACET_OCTA, -BAR_WIDTH, CUT);
		glVertex3f(-FACET_OCTA, BAR_WIDTH, CUT);
		glVertex3f(-FACET_OCTA, CUT, BAR_WIDTH);
		glVertex3f(-FACET_OCTA, CUT, -BAR_WIDTH);
		glVertex3f(-FACET_OCTA, BAR_WIDTH, -CUT);
		glVertex3f(-FACET_OCTA, -BAR_WIDTH, -CUT);
		glEnd();
	    if (topFace == NO_POSITION && rightFace == NO_POSITION
			&& rightBack == NO_POSITION && bottomBack == NO_POSITION) {
		glBegin(GL_POLYGON);
		glNormal3f(1.0, 0.0, 0.0);
		glVertex3f(0, -BAR_WIDTH, -FACET_OCTA);
		glVertex3f(0, BAR_WIDTH, -FACET_OCTA);
		glVertex3f(0, FACET_OCTA, -BAR_WIDTH);
		glVertex3f(0, FACET_OCTA, BAR_WIDTH);
		glVertex3f(0, BAR_WIDTH, FACET_OCTA);
		glVertex3f(0, -BAR_WIDTH, FACET_OCTA);
		glVertex3f(0, -FACET_OCTA, BAR_WIDTH);
		glVertex3f(0, -FACET_OCTA, -BAR_WIDTH);
		glEnd();
	    }
	}
	if (topFace != NO_POSITION || rightFace != NO_POSITION
			|| rightBack != NO_POSITION || bottomBack != NO_POSITION) {
		glBegin(GL_POLYGON);
		glNormal3f(1.0, 0.0, 0.0);
		glVertex3f(FACET_OCTA, -BAR_WIDTH, -CUT); /* BACK RIGHT */
		glVertex3f(FACET_OCTA, BAR_WIDTH, -CUT);
		glVertex3f(FACET_OCTA, CUT, -BAR_WIDTH);
		glVertex3f(FACET_OCTA, CUT, BAR_WIDTH);
		glVertex3f(FACET_OCTA, BAR_WIDTH, CUT);
		glVertex3f(FACET_OCTA, -BAR_WIDTH, CUT);
		glVertex3f(FACET_OCTA, -CUT, BAR_WIDTH);
		glVertex3f(FACET_OCTA, -CUT, -BAR_WIDTH);
		glEnd();
	    if (bottomFace == NO_POSITION && leftFace == NO_POSITION
			&& topBack == NO_POSITION && leftBack == NO_POSITION) {
		glBegin(GL_POLYGON);
		glNormal3f(-1.0, 0.0, 0.0);
		glVertex3f(0, -FACET_OCTA, -BAR_WIDTH);
		glVertex3f(0, -FACET_OCTA, BAR_WIDTH);
		glVertex3f(0, -BAR_WIDTH, FACET_OCTA);
		glVertex3f(0, BAR_WIDTH, FACET_OCTA);
		glVertex3f(0, FACET_OCTA, BAR_WIDTH);
		glVertex3f(0, FACET_OCTA, -BAR_WIDTH);
		glVertex3f(0, BAR_WIDTH, -FACET_OCTA);
		glVertex3f(0, -BAR_WIDTH, -FACET_OCTA);
		glEnd();
	    }
	}
	if (topFace != NO_POSITION && rightFace != NO_POSITION
			&& bottomFace != NO_POSITION && leftFace != NO_POSITION) {
		glBegin(GL_POLYGON);
		glNormal3f(0.0, 1.0, 0.0);
		glVertex3f(-CUT, FACET_OCTA, -BAR_WIDTH); /* TOP */
		glVertex3f(-CUT, FACET_OCTA, BAR_WIDTH);
		glVertex3f(-BAR_WIDTH, FACET_OCTA, CUT);
		glVertex3f(BAR_WIDTH, FACET_OCTA, CUT);
		glVertex3f(CUT, FACET_OCTA, BAR_WIDTH);
		glVertex3f(CUT, FACET_OCTA, -BAR_WIDTH);
		glVertex3f(BAR_WIDTH, FACET_OCTA, -CUT);
		glVertex3f(-BAR_WIDTH, FACET_OCTA, -CUT);
		glEnd();
	    if (topBack == NO_POSITION && rightBack == NO_POSITION
			&& bottomBack == NO_POSITION && leftBack == NO_POSITION) {
		glBegin(GL_POLYGON);
		glNormal3f(0.0, -1.0, 0.0);
		glVertex3f(-BAR_WIDTH, 0, -FACET_OCTA);
		glVertex3f(BAR_WIDTH, 0, -FACET_OCTA);
		glVertex3f(FACET_OCTA, 0, -BAR_WIDTH);
		glVertex3f(FACET_OCTA, 0, BAR_WIDTH);
		glVertex3f(BAR_WIDTH, 0, FACET_OCTA);
		glVertex3f(-BAR_WIDTH, 0, FACET_OCTA);
		glVertex3f(-FACET_OCTA, 0, BAR_WIDTH);
		glVertex3f(-FACET_OCTA, 0, -BAR_WIDTH);
		glEnd();
	    }
	}
	if (topBack != NO_POSITION || rightBack != NO_POSITION
			|| bottomBack != NO_POSITION || leftBack != NO_POSITION) {
		glBegin(GL_POLYGON);
		glNormal3f(0.0, -1.0, 0.0);
		glVertex3f(-BAR_WIDTH, -FACET_OCTA, -CUT); /* BOTTOM */
		glVertex3f(BAR_WIDTH, -FACET_OCTA, -CUT);
		glVertex3f(CUT, -FACET_OCTA, -BAR_WIDTH);
		glVertex3f(CUT, -FACET_OCTA, BAR_WIDTH);
		glVertex3f(BAR_WIDTH, -FACET_OCTA, CUT);
		glVertex3f(-BAR_WIDTH, -FACET_OCTA, CUT);
		glVertex3f(-CUT, -FACET_OCTA, BAR_WIDTH);
		glVertex3f(-CUT, -FACET_OCTA, -BAR_WIDTH);
		glEnd();
	    if (topFace == NO_POSITION && rightFace == NO_POSITION
			&& bottomFace == NO_POSITION && leftFace == NO_POSITION) {
		glBegin(GL_POLYGON);
		glNormal3f(0.0, 1.0, 0.0);
		glVertex3f(-FACET_OCTA, 0, -BAR_WIDTH);
		glVertex3f(-FACET_OCTA, 0, BAR_WIDTH);
		glVertex3f(-BAR_WIDTH, 0, FACET_OCTA);
		glVertex3f(BAR_WIDTH, 0, FACET_OCTA);
		glVertex3f(FACET_OCTA, 0, BAR_WIDTH);
		glVertex3f(FACET_OCTA, 0, -BAR_WIDTH);
		glVertex3f(BAR_WIDTH, 0, -FACET_OCTA);
		glVertex3f(-BAR_WIDTH, 0, -FACET_OCTA);
		glEnd();
	    }
	}
	if (rightFace != NO_POSITION || bottomFace != NO_POSITION
			|| topBack != NO_POSITION || rightBack != NO_POSITION) {
		glBegin(GL_POLYGON);
		glNormal3f(0.0, 0.0, 1.0);
		glVertex3f(-BAR_WIDTH, -CUT, FACET_OCTA); /* RIGHT */
		glVertex3f(BAR_WIDTH, -CUT, FACET_OCTA);
		glVertex3f(CUT, -BAR_WIDTH, FACET_OCTA);
		glVertex3f(CUT, BAR_WIDTH, FACET_OCTA);
		glVertex3f(BAR_WIDTH, CUT, FACET_OCTA);
		glVertex3f(-BAR_WIDTH, CUT, FACET_OCTA);
		glVertex3f(-CUT, BAR_WIDTH, FACET_OCTA);
		glVertex3f(-CUT, -BAR_WIDTH, FACET_OCTA);
		glEnd();
	    if (topFace == NO_POSITION && leftFace == NO_POSITION
			&& bottomBack == NO_POSITION && leftBack == NO_POSITION) {
		glBegin(GL_POLYGON);
		glNormal3f(0.0, 0.0, -1.0);
		glVertex3f(-BAR_WIDTH, -FACET_OCTA, 0);
		glVertex3f(BAR_WIDTH, -FACET_OCTA, 0);
		glVertex3f(FACET_OCTA, -BAR_WIDTH, 0);
		glVertex3f(FACET_OCTA, BAR_WIDTH, 0);
		glVertex3f(BAR_WIDTH, FACET_OCTA, 0);
		glVertex3f(-BAR_WIDTH, FACET_OCTA, 0);
		glVertex3f(-FACET_OCTA, BAR_WIDTH, 0);
		glVertex3f(-FACET_OCTA, -BAR_WIDTH, 0);
		glEnd();
	    }
	}
	if (topFace != NO_POSITION || leftFace != NO_POSITION
			|| bottomBack != NO_POSITION || leftBack != NO_POSITION) {
		glBegin(GL_POLYGON);
		glNormal3f(0.0, 0.0, -1.0);
		glVertex3f(-CUT, -BAR_WIDTH, -FACET_OCTA); /* BACK LEFT */
		glVertex3f(-CUT, BAR_WIDTH, -FACET_OCTA);
		glVertex3f(-BAR_WIDTH, CUT, -FACET_OCTA);
		glVertex3f(BAR_WIDTH, CUT, -FACET_OCTA);
		glVertex3f(CUT, BAR_WIDTH, -FACET_OCTA);
		glVertex3f(CUT, -BAR_WIDTH, -FACET_OCTA);
		glVertex3f(BAR_WIDTH, -CUT, -FACET_OCTA);
		glVertex3f(-BAR_WIDTH, -CUT, -FACET_OCTA);
		glEnd();
	    if (rightFace == NO_POSITION && bottomFace == NO_POSITION
			&& topBack == NO_POSITION && rightBack == NO_POSITION) {
		glBegin(GL_POLYGON);
		glNormal3f(0.0, 0.0, 1.0);
		glVertex3f(-BAR_WIDTH, -FACET_OCTA, 0);
		glVertex3f(BAR_WIDTH, -FACET_OCTA, 0);
		glVertex3f(FACET_OCTA, -BAR_WIDTH, 0);
		glVertex3f(FACET_OCTA, BAR_WIDTH, 0);
		glVertex3f(BAR_WIDTH, FACET_OCTA, 0);
		glVertex3f(-BAR_WIDTH, FACET_OCTA, 0);
		glVertex3f(-FACET_OCTA, BAR_WIDTH, 0);
		glVertex3f(-FACET_OCTA, -BAR_WIDTH, 0);
		glEnd();
	    }
	}

	/* FACES */	
	/* TOP BEHIND */
	if (topFace != NO_POSITION) {
		glBegin(GL_POLYGON);
		glNormal3f(1.0, 1.0, -1.0);
		glVertex3f(CUT, BAR_WIDTH, -FACET_OCTA);
		glVertex3f(BAR_WIDTH, CUT, -FACET_OCTA);
		glVertex3f(BAR_WIDTH, FACET_OCTA, -CUT);
		glVertex3f(CUT, FACET_OCTA, -BAR_WIDTH);
		glVertex3f(FACET_OCTA, CUT, -BAR_WIDTH);
		glVertex3f(FACET_OCTA, BAR_WIDTH, -CUT);
		glEnd();
	}
	/* TOP RIGHT */
	if (rightFace != NO_POSITION) {
		glBegin(GL_POLYGON);
		glNormal3f(1.0, 1.0, 1.0);
		glVertex3f(FACET_OCTA, BAR_WIDTH, CUT);
		glVertex3f(FACET_OCTA, CUT, BAR_WIDTH);
		glVertex3f(CUT, FACET_OCTA, BAR_WIDTH);
		glVertex3f(BAR_WIDTH, FACET_OCTA, CUT);
		glVertex3f(BAR_WIDTH, CUT, FACET_OCTA);
		glVertex3f(CUT, BAR_WIDTH, FACET_OCTA);
		glEnd();
	}
	/* FRONT */
	if (bottomFace != NO_POSITION) {
		glBegin(GL_POLYGON);
		glNormal3f(-1.0, 1.0, 1.0);
		glVertex3f(-CUT, BAR_WIDTH, FACET_OCTA); /* RIGHT */
		glVertex3f(-BAR_WIDTH, CUT, FACET_OCTA);
		glVertex3f(-BAR_WIDTH, FACET_OCTA, CUT); /* TOP */
		glVertex3f(-CUT, FACET_OCTA, BAR_WIDTH);
		glVertex3f(-FACET_OCTA, CUT, BAR_WIDTH); /* LEFT */
		glVertex3f(-FACET_OCTA, BAR_WIDTH, CUT);
		glEnd();
	}
	/* TOP LEFT */
	if (leftFace != NO_POSITION) {
		glBegin(GL_POLYGON);
		glNormal3f(-1.0, 1.0, -1.0);
		glVertex3f(-FACET_OCTA, BAR_WIDTH, -CUT); /* LEFT BOTTOM */
		glVertex3f(-FACET_OCTA, CUT, -BAR_WIDTH);
		glVertex3f(-CUT, FACET_OCTA, -BAR_WIDTH); /* TOP */
		glVertex3f(-BAR_WIDTH, FACET_OCTA, -CUT);
		glVertex3f(-BAR_WIDTH, CUT, -FACET_OCTA); /* FAR LEFT */
		glVertex3f(-CUT, BAR_WIDTH, -FACET_OCTA);
		glEnd();
	}
	/* BOTTOM */
	if (topBack != NO_POSITION) {
		glBegin(GL_POLYGON);
		glNormal3f(-1.0, -1.0, 1.0);
		glVertex3f(-FACET_OCTA, -BAR_WIDTH, CUT);
		glVertex3f(-FACET_OCTA, -CUT, BAR_WIDTH);
		glVertex3f(-CUT, -FACET_OCTA, BAR_WIDTH);
		glVertex3f(-BAR_WIDTH, -FACET_OCTA, CUT);
		glVertex3f(-BAR_WIDTH, -CUT, FACET_OCTA);
		glVertex3f(-CUT, -BAR_WIDTH, FACET_OCTA);
		glEnd();
	}
	/* BOTTOM RIGHT */
	if (rightBack != NO_POSITION) {
		glBegin(GL_POLYGON);
		glNormal3f(1.0, -1.0, 1.0);
		glVertex3f(CUT, -BAR_WIDTH, FACET_OCTA);
		glVertex3f(BAR_WIDTH, -CUT, FACET_OCTA);
		glVertex3f(BAR_WIDTH, -FACET_OCTA, CUT);
		glVertex3f(CUT, -FACET_OCTA, BAR_WIDTH);
		glVertex3f(FACET_OCTA, -CUT, BAR_WIDTH);
		glVertex3f(FACET_OCTA, -BAR_WIDTH, CUT);
		glEnd();
	}
	/* BACK */
	if (bottomBack != NO_POSITION) {
		glBegin(GL_POLYGON);
		glNormal3f(1.0, -1.0, -1.0);
		glVertex3f(FACET_OCTA, -BAR_WIDTH, -CUT);
		glVertex3f(FACET_OCTA, -CUT, -BAR_WIDTH);
		glVertex3f(CUT, -FACET_OCTA, -BAR_WIDTH);
		glVertex3f(BAR_WIDTH, -FACET_OCTA, -CUT);
		glVertex3f(BAR_WIDTH, -CUT, -FACET_OCTA);
		glVertex3f(CUT, -BAR_WIDTH, -FACET_OCTA);
		glEnd();
	}
	/* BOTTOM LEFT */
	if (leftBack != NO_POSITION) {
		glBegin(GL_POLYGON);
		glNormal3f(-1.0, -1.0, -1.0);
		glVertex3f(-CUT, -BAR_WIDTH, -FACET_OCTA);
		glVertex3f(-BAR_WIDTH, -CUT, -FACET_OCTA);
		glVertex3f(-BAR_WIDTH, -FACET_OCTA, -CUT);
		glVertex3f(-CUT, -FACET_OCTA, -BAR_WIDTH);
		glVertex3f(-FACET_OCTA, -CUT, -BAR_WIDTH);
		glVertex3f(-FACET_OCTA, -BAR_WIDTH, -CUT);
		glEnd();
	}
	glPopMatrix();
}

/* This helps to Map sizes for the piece faces */
static int truncUnit[MAX_FACES][6][3] =
{
	{ /* 0 inv Red */
		{1, 3, -2},
		{2, 3, -1},
		{3, 2, -1},
		{3, 1, -2},
		{2, 1, -3},
		{1, 2, -3}
	}, { /* 1 Blue */
		{2, 3, 1},
		{1, 3, 2},
		{1, 2, 3},
		{2, 1, 3},
		{3, 1, 2},
		{3, 2, 1}
	}, { /* 2 inv White */
		{-1, 3, 2},
		{-2, 3, 1},
		{-3, 2, 1},
		{-3, 1, 2},
		{-2, 1, 3},
		{-1, 2, 3}
	}, { /* 3 Magenta */
		{-2, 3, -1},
		{-1, 3, -2},
		{-1, 2, -3},
		{-2, 1, -3},
		{-3, 1, -2},
		{-3, 2, -1}
	}, { /* 4 Orange */
		{-2, -3, 1},
		{-1, -3, 2},
		{-1, -2, 3},
		{-2, -1, 3},
		{-3, -1, 2},
		{-3, -2, 1}
	}, { /* 5 inv Pink */
		{1, -3, 2},
		{2, -3, 1},
		{3, -2, 1},
		{3, -1, 2},
		{2, -1, 3},
		{1, -2, 3}
	}, { /* 6 Green */
		{2, -3, -1},
		{1, -3, -2},
		{1, -2, -3},
		{2, -1, -3},
		{3, -1, -2},
		{3, -2, -1}
	}, { /* 7 inv Yellow */
		{-1, -3, -2},
		{-2, -3, -1},
		{-3, -2, -1},
		{-3, -1, -2},
		{-2, -1, -3},
		{-1, -2, -3}
	}
};

static float stickerCoord[6][3];

static void setStickerCoord(int face, float a, float b, float c)
{
	int i, j, value;
	for (i = 0; i < 6; i++) {
		for (j = 0; j < 3; j++) {
			value = truncUnit[face][i][j];
			switch(value) {
			case -1:
				stickerCoord[i][j] = -a;
				break;
			case 1:
				stickerCoord[i][j] = a;
				break;
			case -2:
				stickerCoord[i][j] = -b;
				break;
			case 2:
				stickerCoord[i][j] = b;
				break;
			case -3:
				stickerCoord[i][j] = -c;
				break;
			case 3:
				stickerCoord[i][j] = c;
				break;
			}
		}
	}
}

static void
drawSticker(OctGLWidget w, int face, int position, Boolean tetra)
{
	float center[3], mid[3], small[3];
	float width = ((tetra) ? 0.075f : 0.02f); /* TODO */
	int color = (int) w->oct.facetLoc[face][position].face;
	int dir = (int) w->oct.facetLoc[face][position].rotation % 3;
	int i, j;

	dir = (3 - dir) % 3; /* triangles drawn CCW but orientation defined CW */
	glBegin(GL_POLYGON);
	if (color < 0 || color > MAX_FACES) {
		(void) printf("color not defined %d %d\n", face, position);
		return;
	}
	glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, face_material[color]);
	if (tetra)
		setStickerCoord(face, -STICKER_TETRA3, STICKER_TETRA2, STICKER_LENGTH2);
	else
		setStickerCoord(face, CUT, GAP_WIDTH, STICKER_OCTA2);
	for (j = 0; j < 3; j++) {
		center[j] = 0;
		mid[j] = 0;
	}
	for (i = 0; i < 6; i++) {
		glVertex3f(stickerCoord[i][0], stickerCoord[i][1], stickerCoord[i][2]);
		if (i % 2 == 0) {
			for (j = 0; j < 3; j++) {
				center[j] += stickerCoord[i][j];
			}
		}
		if (dir * 2 != i && dir * 2 + 1 != i) {
			for (j = 0; j < 3; j++) {
				mid[j] += stickerCoord[i][j];
			}
		}
	}
	glEnd();
	if (w->oct.orient) {
		for (j = 0; j < 3; j++) {
			center[j] = center[j] / 3;
			mid[j] = mid[j] / 4;
			small[j] = mid[j] * width;
		}
		glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, face_material[BORDER_FACE]);
		/* GL_LINES does not work well */
		/* when is first wrong and when is first right */
		glBegin(GL_POLYGON);
		glVertex3f(center[0] - small[0], center[1] - small[1], center[2] - small[2]);
		glVertex3f(center[0] + small[0], center[1] + small[1], center[2] + small[2]);
		glVertex3f(mid[0] + small[0], mid[1] + small[1], mid[2] + small[2]);
		glVertex3f(mid[0] - small[0], mid[1] - small[1], mid[2] - small[2]);
		glEnd();
		glBegin(GL_POLYGON);
		glVertex3f(center[0] + small[0], center[1] + small[1], center[2] + small[2]);
		glVertex3f(center[0] - small[0], center[1] - small[1], center[2] - small[2]);
		glVertex3f(mid[0] - small[0], mid[1] - small[1], mid[2] - small[2]);
		glVertex3f(mid[0] + small[0], mid[1] + small[1], mid[2] + small[2]);
		glEnd();
	}
	if (w->oct.currentFace == face &&
			w->oct.currentPosition == position) {
		glBegin(GL_POLYGON);
		glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, face_material[BORDER_FACE]);
		if (tetra)
			setStickerCoord(face, -STICKER_TETRA3, STICKER_TETRA2, STICKER_LENGTH2);
		else
			setStickerCoord(face, CUT, GAP_WIDTH2, SELECT_OCTA2);
		for (i = 0; i < 6; i++) {
			glVertex3f(stickerCoord[i][0], stickerCoord[i][1], stickerCoord[i][2]);
		}
		glEnd();
	}
}

/* 2 different orientations of tetrahedron */
static void
drawRegTetraFacet(OctGLWidget w, int leftFace, int rightFace, int topBack, int bottomBack)
{
	drawStickerlessTetra();
	glPushMatrix();
	if (leftFace != NO_POSITION) { /* 3 MAGENTA */
		glNormal3f(-1.0, 1.0, -1.0);
		drawSticker(w, LEFT_FACE, leftFace, True);
	}
	if (rightFace != NO_POSITION) { /* 1 BLUE */
		glNormal3f(1.0, 1.0, 1.0);
		drawSticker(w, RIGHT_FACE, rightFace, True);
	}
	if (topBack != NO_POSITION) { /* 4 ORANGE */
		glNormal3f(-1.0, -1.0, 1.0);
		drawSticker(w, TOP_BACK, topBack, True);
	}
	if (bottomBack != NO_POSITION) { /* 6 GREEN */
		glNormal3f(1.0, -1.0, -1.0);
		drawSticker(w, BOTTOM_BACK, bottomBack, True);
	}
	glPopMatrix();
}

static void
drawInvTetraFacet(OctGLWidget w, int topFace, int bottomFace, int leftBack, int rightBack)
{
	drawStickerlessInvTetra();
	glPushMatrix();
	if (topFace != NO_POSITION) { /* 0 RED */
		glNormal3f(1.0, 1.0, -1.0);
		drawSticker(w, TOP_FACE, topFace, True);
	}
	if (bottomFace != NO_POSITION) { /* 2 WHITE */
		glNormal3f(-1.0, 1.0, 1.0);
		drawSticker(w, BOTTOM_FACE, bottomFace, True);
	}
	if (leftBack != NO_POSITION) { /* 7 YELLOW */
		glNormal3f(1.0, -1.0, 1.0);
		drawSticker(w, LEFT_BACK, leftBack, True);
	}
	if (rightBack != NO_POSITION) { /* 5 PINK */
		glNormal3f(1.0, -1.0, 1.0);
		drawSticker(w, RIGHT_BACK, rightBack, True);
	}
	glPopMatrix();
}

/* combine into one routine to be compatible with octa drawing */
static void
drawTetraFacet(OctGLWidget w,
		int topFace, int rightFace, int bottomFace, int leftFace,
		int topBack, int rightBack, int bottomBack, int leftBack)
{
	if (topFace != -1 || bottomFace != -1
			|| leftBack != -1 || rightBack != -1)
		drawInvTetraFacet(w, topFace, bottomFace, leftBack, rightBack);
	if (leftFace != -1 || rightFace != -1
			|| topBack != -1 || bottomBack != -1)
		drawRegTetraFacet(w, leftFace, rightFace, topBack, bottomBack);
}

static void
drawOctaFacet(OctGLWidget w,
		int topFace, int rightFace, int bottomFace, int leftFace,
		int topBack, int rightBack, int bottomBack, int leftBack)
{
	glPushMatrix();
	if (w->octGL.movement.style == PERIOD4) /* draw visible parts of the octahedrons */
		drawStickerlessOcta(topFace, rightFace, bottomFace, leftFace,
			topBack, rightBack, bottomBack, leftBack);
	else
		drawStickerlessOcta(1, 1, 1, 1, 1, 1, 1, 1);
	/* TOP BEHIND */
	if (topFace != NO_POSITION) { /* RED */
		glNormal3f(1.0, 1.0, -1.0);
		drawSticker(w, TOP_FACE, topFace, False);
	}
	/* TOP RIGHT */
	if (rightFace != NO_POSITION) { /* BLUE */
		glNormal3f(1.0, 1.0, 1.0);
		drawSticker(w, RIGHT_FACE, rightFace, False);
	}
	/* FRONT */
	if (bottomFace != NO_POSITION) { /* WHITE */
		glNormal3f(-1.0, 1.0, 1.0);
		drawSticker(w, BOTTOM_FACE, bottomFace, False);
	}
	/* TOP LEFT */
	if (leftFace != NO_POSITION) { /* MAGENTA */
		glNormal3f(-1.0, 1.0, -1.0);
		drawSticker(w, LEFT_FACE, leftFace, False);
	}
	/* BOTTOM */
	if (topBack != NO_POSITION) { /* ORANGE */
		glNormal3f(-1.0, -1.0, 1.0);
		drawSticker(w, TOP_BACK, topBack, False);
	}
	/* BOTTOM RIGHT */
	if (rightBack != NO_POSITION) { /* PINK */
		glNormal3f(1.0, -1.0, 1.0);
		drawSticker(w, RIGHT_BACK, rightBack, False);
	}
	/* BACK */
	if (bottomBack != NO_POSITION) { /* GREEN */
		glNormal3f(1.0, -1.0, -1.0);
		drawSticker(w, BOTTOM_BACK, bottomBack, False);
	}
	/* BOTTOM LEFT */
	if (leftBack != NO_POSITION) { /* YELLOW */
		glNormal3f(1.0, -1.0, 1.0);
		drawSticker(w, LEFT_BACK, leftBack, False);
	}
	glPopMatrix();
}

static void
drawFacet(OctGLWidget w,
		int topFace, int rightFace, int bottomFace, int leftFace,
		int topBack, int rightBack, int bottomBack, int leftBack,
		Boolean tetra)
{
	if (tetra)
		drawTetraFacet(w, topFace, rightFace, bottomFace, leftFace,
			topBack, rightBack, bottomBack, leftBack);
	else
		drawOctaFacet(w, topFace, rightFace, bottomFace, leftFace,
			topBack, rightBack, bottomBack, leftBack);
}

typedef struct _FaceDepth {
	int face, depth;
} FaceDepth;

static void
faceDepth(OctWidget w, int face, int position, int direction, FaceDepth *fd)
{
	RTT rtt;

	toRTT(position, &rtt);
	if ((face == 0 && (direction == BR || direction == TL)) ||
			(face == 1 && (direction == TOP || direction == BOTTOM)) ||
			(face == 2 && (direction == TR || direction == BL)) ||
			(face == 6 && (direction == BR || direction == TL)) ||
			(face == 7 && (direction == TOP || direction == BOTTOM)) ||
			(face == 4 && (direction == TR || direction == BL))) {
		fd->face = 3;
		if (face < 4)
			fd->depth = ((face == 1) ? rtt.row :
				((face == 0) ? rtt.tlbr : rtt.trbl));
		else
			fd->depth = w->oct.size - 1 -
				((face == 7) ? rtt.row :
				((face == 4) ? rtt.trbl : rtt.tlbr));
	} else if ((face == 0 && (direction == TR || direction == BL)) ||
			(face == 3 && (direction == TOP || direction == BOTTOM)) ||
			(face == 2 && (direction == BR || direction == TL)) ||
			(face == 6 && (direction == TR || direction == BL)) ||
			(face == 5 && (direction == TOP || direction == BOTTOM)) ||
			(face == 4 && (direction == BR || direction == TL))) {
		fd->face = 1;
		if (face < 4)
			fd->depth = ((face == 3) ? rtt.row :
				((face == 0) ? rtt.trbl : rtt.tlbr));
		else
			fd->depth = w->oct.size - 1 -
				((face == 5) ? rtt.row :
				((face == 4) ? rtt.tlbr : rtt.trbl));
	} else if ((face == 1 && (direction == TR || direction == BL)) ||
			(face == 2 && (direction == RIGHT || direction == LEFT)) ||
			(face == 3 && (direction == BR || direction == TL)) ||
			(face == 5 && (direction == TR || direction == BL)) ||
			(face == 6 && (direction == RIGHT || direction == LEFT)) ||
			(face == 7 && (direction == BR || direction == TL))) {
		fd->face = 0;
		if (face < 4)
			fd->depth = ((face == 2) ? rtt.row :
				((face == 1) ? rtt.tlbr : rtt.trbl));
		else
			fd->depth = w->oct.size - 1 -
				((face == 6) ? rtt.row :
				((face == 5) ? rtt.tlbr : rtt.trbl));
	} else if ((face == 3 && (direction == TR || direction == BL)) ||
			(face == 0 && (direction == RIGHT || direction == LEFT)) ||
			(face == 1 && (direction == BR || direction == TL)) ||
			(face == 7 && (direction == TR || direction == BL)) ||
			(face == 4 && (direction == RIGHT || direction == LEFT)) ||
			(face == 5 && (direction == BR || direction == TL))) {
		fd->face = 2;
		if (face < 4)
			fd->depth = ((face == 0) ? rtt.row :
				((face == 1) ? rtt.trbl : rtt.tlbr));
		else
			fd->depth = w->oct.size - 1 -
				((face == 4) ? rtt.row :
				((face == 5) ? rtt.trbl : rtt.tlbr));
	} else {
		if (face != -1) {
			(void) printf("faceDepth error: face %d, position %d, direction %d\n",
				face, position, direction);
		}
		fd->face = 0;
		fd->depth = 0;
	}
}

static void
drawFaces(OctGLWidget w, int face, int position, int direction,
		Boolean use, Boolean all)
{
	int s0, s1, s2, i, j, k;
	int size = w->oct.size;
	Boolean tetra, sticky = w->oct.sticky;
	RTT rtt;
	FaceDepth fd;

	toRTT(position, &rtt);
	faceDepth((OctWidget) w, face, position, direction, &fd);
#ifdef DEBUG
	(void) printf("drawFaces: faceDepth face %d, depth %d\n", fd.face, fd.depth);
#endif
	if (size == 1 && (all || use))
		drawOctaFacet(w, 0, 0, 0, 0, 0, 0, 0, 0);
	if (size > 1) { /* CORNERS */
		s2 = 2 * size - 2;
		j = (size - 1) * (size - 1);
		k = size * size - 1;
		if (all || (use && (fd.face == 0 || fd.face == 1) && fd.depth == 0)
				|| (use && (fd.face == 2 || fd.face == 3) && fd.depth == size - 1)
				|| (!use && (fd.face == 0 || fd.face == 1) && fd.depth != 0)
				|| (!use && (fd.face == 2 || fd.face == 3) && fd.depth != size - 1)) {
			glPushMatrix();
			glTranslate(s2 * FACET_LENGTH, 0, 0);
			drawOctaFacet(w, j, k, -1, -1, -1, j, k, -1); /* TR */
			glPopMatrix();
		}
		if (all || (use && (fd.face == 1 || fd.face == 2) && fd.depth == 0)
				|| (use && (fd.face == 0 || fd.face == 3) && fd.depth == size - 1)
				|| (!use && (fd.face == 1 || fd.face == 2) && fd.depth != 0)
				|| (!use && (fd.face == 0 || fd.face == 3) && fd.depth != size - 1)) {
			glPushMatrix();
			glTranslate(0, 0, s2 * FACET_LENGTH);
			drawOctaFacet(w, -1, j, k, -1, j, k, -1, -1); /* BR */
			glPopMatrix();
		}
		if (all || (use && (fd.face == 2 || fd.face == 3) && fd.depth == 0)
				|| (use && (fd.face == 0 || fd.face == 1) && fd.depth == size - 1)
				|| (!use && (fd.face == 2 || fd.face == 3) && fd.depth != 0)
				|| (!use && (fd.face == 0 || fd.face == 1) && fd.depth != size - 1)) {
			glPushMatrix();
			glTranslate(-s2 * FACET_LENGTH, 0, 0);
			drawOctaFacet(w, -1, -1, j, k, k, -1, -1, j); /* BL */
			glPopMatrix();
		}
		if (all || (use && (fd.face == 0 || fd.face == 3) && fd.depth == 0)
				|| (use && (fd.face == 1 || fd.face == 2) && fd.depth == size - 1)
				|| (!use && (fd.face == 0 || fd.face == 3) && fd.depth != 0)
				|| (!use && (fd.face == 1 || fd.face == 2) && fd.depth != size - 1)) {
			glPushMatrix();
			glTranslate(0, 0, -s2 * FACET_LENGTH);
			drawOctaFacet(w, k, -1, -1, j, -1, -1, j, k); /* TL */
			glPopMatrix();
		}
		if (all || (use && fd.depth == 0)
				|| (!use && fd.depth != 0)) {
			glPushMatrix();
			glTranslate(0, s2 * FACET_LENGTH, 0);
			drawOctaFacet(w, 0, 0, 0, 0, -1, -1, -1, -1); /* TOP */
			glPopMatrix();
		}
		if (all || (use && fd.depth == size - 1)
				|| (!use && fd.depth != size - 1)) {
			glPushMatrix();
			glTranslate(0, -s2 * FACET_LENGTH, 0);
			drawOctaFacet(w, -1, -1, -1, -1, 0, 0, 0, 0); /* BOTTOM */
			glPopMatrix();
		}
	}
	if (size > 1 && size % 3 != 0) { /* CENTERS */
		tetra = (size % 3 == 2); /* 2, 6, 12, 20, 30 */
		if (tetra) {
			s2 = ((size - 2) / 3) * 2 + 1;
		} else {
			s2 = ((size - 1) / 3) * 2;
		}
		k = s2 * s2 + s2;
		i = s2;
		s1 = size - 1 - s2;
		if (all || (!sticky && ((use && fd.face == 0 && fd.depth == 0)
				|| (use && (fd.face == 1 || fd.face == 3) && fd.depth == s1)
				|| (use && fd.face == 2 && fd.depth == s2)
				|| (!use && fd.face == 0 && fd.depth != 0)
				|| (!use && (fd.face == 1 || fd.face == 3) && fd.depth != s1)
				|| (!use && fd.face == 2 && fd.depth != s2)))
			|| (sticky && ((use && fd.face == 0 && fd.depth == 0)
				|| (use && fd.face != 0 && (fd.depth == 1 || fd.depth == 2))
				|| (!use && fd.face == 0 && fd.depth != 0)
				|| (!use && fd.face != 0 && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(i * FACET_LENGTH, i * FACET_LENGTH, -i * FACET_LENGTH);
			drawFacet(w, k, -1, -1, -1, -1, -1, -1, -1, tetra); /* 0 */
			glPopMatrix();
		}
		if (all || (!sticky && ((use && fd.face == 1 && fd.depth == 0)
				|| (use && (fd.face == 0 || fd.face == 2) && fd.depth == s1)
				|| (use && fd.face == 3 && fd.depth == s2)
				|| (!use && fd.face == 1 && fd.depth != 0)
				|| (!use && (fd.face == 0 || fd.face == 2) && fd.depth != s1)
				|| (!use && fd.face == 3 && fd.depth != s2)))
			|| (sticky && ((use && fd.face == 1 && fd.depth == 0)
				|| (use && fd.face != 1 && (fd.depth == 1 || fd.depth == 2))
				|| (!use && fd.face == 1 && fd.depth != 0)
				|| (!use && fd.face != 1 && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(i * FACET_LENGTH, i * FACET_LENGTH, i * FACET_LENGTH);
			drawFacet(w, -1, k, -1, -1, -1, -1, -1, -1, tetra); /* 1 */
			glPopMatrix();
		}
		if (all || (!sticky && ((use && fd.face == 2 && fd.depth == 0)
				|| (use && (fd.face == 1 || fd.face == 3) && fd.depth == s1)
				|| (use && fd.face == 0 && fd.depth == s2)
				|| (!use && fd.face == 2 && fd.depth != 0)
				|| (!use && (fd.face == 1 || fd.face == 3) && fd.depth != s1)
				|| (!use && fd.face == 0 && fd.depth != s2)))
			|| (sticky && ((use && fd.face == 2 && fd.depth == 0)
				|| (use && fd.face != 2 && (fd.depth == 1 || fd.depth == 2))
				|| (!use && fd.face == 2 && fd.depth != 0)
				|| (!use && fd.face != 2 && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(-i * FACET_LENGTH, i * FACET_LENGTH, i * FACET_LENGTH);
			drawFacet(w, -1, -1, k, -1, -1, -1, -1, -1, tetra); /* 2 */
			glPopMatrix();
		}
		if (all || (!sticky && ((use && fd.face == 3 && fd.depth == 0)
				|| (use && (fd.face == 0 || fd.face == 2) && fd.depth == s1)
				|| (use && fd.face == 1 && fd.depth == s2)
				|| (!use && fd.face == 3 && fd.depth != 0)
				|| (!use && (fd.face == 0 || fd.face == 2) && fd.depth != s1)
				|| (!use && fd.face == 1 && fd.depth != s2)))
			|| (sticky && ((use && fd.face == 3 && fd.depth == 0)
				|| (use && fd.face != 3 && (fd.depth == 1 || fd.depth == 2))
				|| (!use && fd.face == 3 && fd.depth != 0)
				|| (!use && fd.face != 3 && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(-i * FACET_LENGTH, i * FACET_LENGTH, -i * FACET_LENGTH);
			drawFacet(w, -1, -1, -1, k, -1, -1, -1, -1, tetra); /* 3 */
			glPopMatrix();
		}
		if (all || (!sticky && ((use && fd.face == 0 && fd.depth == size - 1)
				|| (use && (fd.face == 1 || fd.face == 3) && fd.depth == s2)
				|| (use && fd.face == 2 && fd.depth == s1)
				|| (!use && fd.face == 0 && fd.depth != size - 1)
				|| (!use && (fd.face == 1 || fd.face == 3) && fd.depth != s2)
				|| (!use && fd.face == 2 && fd.depth != s1)))
			|| (sticky && ((use && fd.face == 0 && fd.depth == size - 1)
				|| (use && fd.face != 0 && (fd.depth == 1 || fd.depth == 2))
				|| (!use && fd.face == 0 && fd.depth != size - 1)
				|| (!use && fd.face != 0 && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(-i * FACET_LENGTH, -i * FACET_LENGTH, i * FACET_LENGTH);
			drawFacet(w, -1, -1, -1, -1, k, -1, -1, -1, tetra); /* 4 */
			glPopMatrix();
		}
		if (all || (!sticky && ((use && fd.face == 3 && fd.depth == size - 1)
				|| (use && (fd.face == 0 || fd.face == 2) && fd.depth == s2)
				|| (use && fd.face == 1 && fd.depth == s1)
				|| (!use && fd.face == 3 && fd.depth != size - 1)
				|| (!use && (fd.face == 0 || fd.face == 2) && fd.depth != s2)
				|| (!use && fd.face == 1 && fd.depth != s1)))
			|| (sticky && ((use && fd.face == 3 && fd.depth == size - 1)
				|| (use && fd.face != 3 && (fd.depth == 1 || fd.depth == 2))
				|| (!use && fd.face == 3 && fd.depth != size - 1)
				|| (!use && fd.face != 3 && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(i * FACET_LENGTH, -i * FACET_LENGTH, i * FACET_LENGTH);
			drawFacet(w, -1, -1, -1, -1, -1, k, -1, -1, tetra); /* 5 */
			glPopMatrix();
		}
		if (all || (!sticky && ((use && fd.face == 2 && fd.depth == size - 1)
				|| (use && (fd.face == 1 || fd.face == 3) && fd.depth == s2)
				|| (use && fd.face == 0 && fd.depth == s1)
				|| (!use && fd.face == 2 && fd.depth != size - 1)
				|| (!use && (fd.face == 1 || fd.face == 3) && fd.depth != s2)
				|| (!use && fd.face == 0 && fd.depth != s1)))
			|| (sticky && ((use && fd.face == 2 && fd.depth == size - 1)
				|| (use && fd.face != 2 && (fd.depth == 1 || fd.depth == 2))
				|| (!use && fd.face == 2 && fd.depth != size - 1)
				|| (!use && fd.face != 2 && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(i * FACET_LENGTH, -i * FACET_LENGTH, -i * FACET_LENGTH);
			drawFacet(w, -1, -1, -1, -1, -1, -1, k, -1, tetra); /* 6 */
			glPopMatrix();
		}
		if (all || (!sticky && ((use && fd.face == 1 && fd.depth == size - 1)
				|| (use && (fd.face == 0 || fd.face == 2) && fd.depth == s2)
				|| (use && fd.face == 3 && fd.depth == s1)
				|| (!use && fd.face == 1 && fd.depth != size - 1)
				|| (!use && (fd.face == 0 || fd.face == 2) && fd.depth != s2)
				|| (!use && fd.face == 3 && fd.depth != s1)))
			|| (sticky && ((use && fd.face == 1 && fd.depth == size - 1)
				|| (use && fd.face != 1 && (fd.depth == 1 || fd.depth == 2))
				|| (!use && fd.face == 1 && fd.depth != size - 1)
				|| (!use && fd.face != 1 && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(-i * FACET_LENGTH, -i * FACET_LENGTH, -i * FACET_LENGTH);
			drawFacet(w, -1, -1, -1, -1, -1, -1, -1, k, tetra); /* 7 */
			glPopMatrix();
		}
	}
	if (size > 2) { /* CORNERS - 1 */
		s0 = (size - 2) * 2 + 1;
		j = (size - 1) * (size - 1) + 1; /* 5, */
		k = size * size - 2; /* 7, */
		if (all || (!sticky && ((use && fd.face != 2 && fd.depth == 0)
				|| (use && fd.face == 2 && fd.depth == 1)
				|| (!use && fd.face != 2 && fd.depth != 0)
				|| (!use && fd.face == 2 && fd.depth != 1)))
			|| (sticky && ((use && fd.face != 2 && fd.depth == 0)
				|| (use && fd.face == 2 && (fd.depth == 1 || fd.depth == 2))
				|| (!use && fd.face != 2 && fd.depth != 0)
				|| (!use && fd.face == 2 && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(FACET_LENGTH, s0 * FACET_LENGTH, -FACET_LENGTH);
			drawTetraFacet(w, 2, -1, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && (fd.face == 0 || fd.face == 1) && fd.depth == 0)
				|| (use && fd.face == 3 && fd.depth == size - 2)
				|| (use && fd.face == 2 && fd.depth == size - 1)
				|| (!use && (fd.face == 0 || fd.face == 1) && fd.depth != 0)
				|| (!use && fd.face == 3 && fd.depth != size - 2)
				|| (!use && fd.face == 2 && fd.depth != size - 1)))
			|| (sticky && ((use && (fd.face == 0 || fd.face == 1) && fd.depth == 0)
				|| (use && fd.face == 3 && (fd.depth == 1 || fd.depth == 2))
				|| (use && fd.face == 2 && fd.depth == size - 1)
				|| (!use && (fd.face == 0 || fd.face == 1) && fd.depth != 0)
				|| (!use && fd.face == 3 && fd.depth != 1 && fd.depth != 2)
				|| (!use && fd.face == 2 && fd.depth != size - 1)))) {
			glPushMatrix();
			glTranslate(s0 * FACET_LENGTH, FACET_LENGTH, -FACET_LENGTH);
			drawTetraFacet(w, j, -1, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && (fd.face == 0 || fd.face == 3) && fd.depth == 0)
				|| (use && fd.face == 1 && fd.depth == size - 2)
				|| (use && fd.face == 2 && fd.depth == size - 1)
				|| (!use && (fd.face == 0 || fd.face == 3) && fd.depth != 0)
				|| (!use && fd.face == 1 && fd.depth != size - 2)
				|| (!use && fd.face == 2 && fd.depth != size - 1)))
			|| (sticky && ((use && (fd.face == 0 || fd.face == 3) && fd.depth == 0)
				|| (use && fd.face == 1 && (fd.depth == 1 || fd.depth == 2))
				|| (use && fd.face == 2 && fd.depth == size - 1)
				|| (!use && (fd.face == 0 || fd.face == 3) && fd.depth != 0)
				|| (!use && fd.face == 1 && fd.depth != 1 && fd.depth != 2)
				|| (!use && fd.face == 2 && fd.depth != size - 1)))) {
			glPushMatrix();
			glTranslate(FACET_LENGTH, FACET_LENGTH, -s0 * FACET_LENGTH);
			drawTetraFacet(w, k, -1, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		/* 1 */
		if (all || (!sticky && ((use && fd.face != 3 && fd.depth == 0)
				|| (use && fd.face == 3 && fd.depth == 1)
				|| (!use && fd.face != 3 && fd.depth != 0)
				|| (!use && fd.face == 3 && fd.depth != 1)))
			|| (sticky && ((use && fd.face != 3 && fd.depth == 0)
				|| (use && fd.face == 3 && (fd.depth == 1 || fd.depth == 2))
				|| (!use && fd.face != 3 && fd.depth != 0)
				|| (!use && fd.face == 3 && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(FACET_LENGTH, s0 * FACET_LENGTH, FACET_LENGTH);
			drawTetraFacet(w, -1, 2, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && (fd.face == 1 || fd.face == 2) && fd.depth == 0)
				|| (use && fd.face == 0 && fd.depth == size - 2)
				|| (use && fd.face == 3 && fd.depth == size - 1)
				|| (!use && (fd.face == 1 || fd.face == 2) && fd.depth != 0)
				|| (!use && fd.face == 0 && fd.depth != size - 2)
				|| (!use && fd.face == 3 && fd.depth != size - 1)))
			|| (sticky && ((use && (fd.face == 1 || fd.face == 2) && fd.depth == 0)
				|| (use && fd.face == 0 && (fd.depth == 1 || fd.depth == 2))
				|| (use && fd.face == 3 && fd.depth == size - 1)
				|| (!use && (fd.face == 1 || fd.face == 2) && fd.depth != 0)
				|| (!use && fd.face == 0 && fd.depth != 1 && fd.depth != 2)
				|| (!use && fd.face == 3 && fd.depth != size - 1)))) {
			glPushMatrix();
			glTranslate(FACET_LENGTH, FACET_LENGTH, s0 * FACET_LENGTH);
			drawTetraFacet(w, -1, j, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && (fd.face == 0 || fd.face == 1) && fd.depth == 0)
				|| (use && fd.face == 2 && fd.depth == size - 2)
				|| (use && fd.face == 3 && fd.depth == size - 1)
				|| (!use && (fd.face == 0 || fd.face == 1) && fd.depth != 0)
				|| (!use && fd.face == 2 && fd.depth != size - 2)
				|| (!use && fd.face == 3 && fd.depth != size - 1)))
			|| (sticky && ((use && (fd.face == 0 || fd.face == 1) && fd.depth == 0)
				|| (use && fd.face == 2 && (fd.depth == 1 || fd.depth == 2))
				|| (use && fd.face == 3 && fd.depth == size - 1)
				|| (!use && (fd.face == 0 || fd.face == 1) && fd.depth != 0)
				|| (!use && fd.face == 2 && fd.depth != 1 && fd.depth != 2)
				|| (!use && fd.face == 3 && fd.depth != size - 1)))) {
			glPushMatrix();
			glTranslate(s0 * FACET_LENGTH, FACET_LENGTH, FACET_LENGTH);
			drawTetraFacet(w, -1, k, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		/* 2 */
		if (all || (!sticky && ((use && fd.face != 0 && fd.depth == 0)
				|| (use && fd.face == 0 && fd.depth == 1)
				|| (!use && fd.face != 0 && fd.depth != 0)
				|| (!use && fd.face == 0 && fd.depth != 1)))
			|| (sticky && ((use && fd.face != 0 && fd.depth == 0)
				|| (use && fd.face == 0 && (fd.depth == 1 || fd.depth == 2))
				|| (!use && fd.face != 0 && fd.depth != 0)
				|| (!use && fd.face == 0 && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(-FACET_LENGTH, s0 * FACET_LENGTH, FACET_LENGTH);
			drawTetraFacet(w, -1, -1, 2, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && (fd.face == 2 || fd.face == 3) && fd.depth == 0)
				|| (use && fd.face == 1 && fd.depth == size - 2)
				|| (use && fd.face == 0 && fd.depth == size - 1)
				|| (!use && (fd.face == 2 || fd.face == 3) && fd.depth != 0)
				|| (!use && fd.face == 1 && fd.depth != size - 2)
				|| (!use && fd.face == 0 && fd.depth != size - 1)))
			|| (sticky && ((use && (fd.face == 2 || fd.face == 3) && fd.depth == 0)
				|| (use && fd.face == 1 && (fd.depth == 1 || fd.depth == 2))
				|| (use && fd.face == 0 && fd.depth == size - 1)
				|| (!use && (fd.face == 2 || fd.face == 3) && fd.depth != 0)
				|| (!use && fd.face == 1 && fd.depth != 1 && fd.depth != 2)
				|| (!use && fd.face == 0 && fd.depth != size - 1)))) {
			glPushMatrix();
			glTranslate(-s0 * FACET_LENGTH, FACET_LENGTH, FACET_LENGTH);
			drawTetraFacet(w, -1, -1, j, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && (fd.face == 1 || fd.face == 2) && fd.depth == 0)
				|| (use && fd.face == 3 && fd.depth == size - 2)
				|| (use && fd.face == 0 && fd.depth == size - 1)
				|| (!use && (fd.face == 1 || fd.face == 2) && fd.depth != 0)
				|| (!use && fd.face == 3 && fd.depth != size - 2)
				|| (!use && fd.face == 0 && fd.depth != size - 1)))
			|| (sticky && ((use && (fd.face == 1 || fd.face == 2) && fd.depth == 0)
				|| (use && fd.face == 3 && (fd.depth == 1 || fd.depth == 2))
				|| (use && fd.face == 0 && fd.depth == size - 1)
				|| (!use && (fd.face == 1 || fd.face == 2) && fd.depth != 0)
				|| (!use && fd.face == 3 && fd.depth != 1 && fd.depth != 2)
				|| (!use && fd.face == 0 && fd.depth != size - 1)))) {
			glPushMatrix();
			glTranslate(-FACET_LENGTH, FACET_LENGTH, s0 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, k, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		/* 3 */
		if (all || (!sticky && ((use && fd.face != 1 && fd.depth == 0)
				|| (use && fd.face == 1 && fd.depth == 1)
				|| (!use && fd.face != 1 && fd.depth != 0)
				|| (!use && fd.face == 1 && fd.depth != 1)))
			|| (sticky && ((use && fd.face != 1 && fd.depth == 0)
				|| (use && fd.face == 1 && (fd.depth == 1 || fd.depth == 2))
				|| (!use && fd.face != 1 && fd.depth != 0)
				|| (!use && fd.face == 1 && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(-FACET_LENGTH, s0 * FACET_LENGTH, -FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, 2, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && (fd.face == 0 || fd.face == 3) && fd.depth == 0)
				|| (use && fd.face == 2 && fd.depth == size - 2)
				|| (use && fd.face == 1 && fd.depth == size - 1)
				|| (!use && (fd.face == 0 || fd.face == 3) && fd.depth != 0)
				|| (!use && fd.face == 2 && fd.depth != size - 2)
				|| (!use && fd.face == 1 && fd.depth != size - 1)))
			|| (sticky && ((use && (fd.face == 0 || fd.face == 3) && fd.depth == 0)
				|| (use && fd.face == 2 && (fd.depth == 1 || fd.depth == 2))
				|| (use && fd.face == 1 && fd.depth == size - 1)
				|| (!use && (fd.face == 0 || fd.face == 3) && fd.depth != 0)
				|| (!use && fd.face == 2 && fd.depth != 1 && fd.depth != 2)
				|| (!use && fd.face == 1 && fd.depth != size - 1)))) {
			glPushMatrix();
			glTranslate(-FACET_LENGTH, FACET_LENGTH, -s0 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, j, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && (fd.face == 2 || fd.face == 3) && fd.depth == 0)
				|| (use && fd.face == 0 && fd.depth == size - 2)
				|| (use && fd.face == 1 && fd.depth == size - 1)
				|| (!use && (fd.face == 2 || fd.face == 3) && fd.depth != 0)
				|| (!use && fd.face == 0 && fd.depth != size - 2)
				|| (!use && fd.face == 1 && fd.depth != size - 1)))
			|| (sticky && ((use && (fd.face == 2 || fd.face == 3) && fd.depth == 0)
				|| (use && fd.face == 0 && (fd.depth == 1 || fd.depth == 2))
				|| (use && fd.face == 1 && fd.depth == size - 1)
				|| (!use && (fd.face == 2 || fd.face == 3) && fd.depth != 0)
				|| (!use && fd.face == 0 && fd.depth != 1 && fd.depth != 2)
				|| (!use && fd.face == 1 && fd.depth != size - 1)))) {
			glPushMatrix();
			glTranslate(-s0 * FACET_LENGTH, FACET_LENGTH, -FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, k, -1, -1, -1, -1);
			glPopMatrix();
		}
		/* 4 */
		if (all || (!sticky && ((use && fd.face != 2 && fd.depth == size - 1)
				|| (use && fd.face == 2 && fd.depth == size - 2)
				|| (!use && fd.face != 2 && fd.depth != size - 1)
				|| (!use && fd.face == 2 && fd.depth != size - 2)))
			|| (sticky && ((use && fd.face != 2 && fd.depth == size - 1)
				|| (use && fd.face == 2 && (fd.depth == 1 || fd.depth == 2))
				|| (!use && fd.face != 2 && fd.depth != size - 1)
				|| (!use && fd.face == 2 && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(-FACET_LENGTH, -s0 * FACET_LENGTH, FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, 2, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && (fd.face == 0 || fd.face == 3) && fd.depth == size - 1)
				|| (use && fd.face == 1 && fd.depth == 1)
				|| (use && fd.face == 2 && fd.depth == 0)
				|| (!use && (fd.face == 0 || fd.face == 3) && fd.depth != size - 1)
				|| (!use && fd.face == 1 && fd.depth != 1)
				|| (!use && fd.face == 2 && fd.depth != 0)))
			|| (sticky && ((use && (fd.face == 0 || fd.face == 3) && fd.depth == size - 1)
				|| (use && fd.face == 1 && (fd.depth == 1 || fd.depth == 2))
				|| (use && fd.face == 2 && fd.depth == 0)
				|| (!use && (fd.face == 0 || fd.face == 3) && fd.depth != size - 1)
				|| (!use && fd.face == 1 && fd.depth != 1 && fd.depth != 2)
				|| (!use && fd.face == 2 && fd.depth != 0)))) {
			glPushMatrix();
			glTranslate(-FACET_LENGTH, -FACET_LENGTH, s0 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, j, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && (fd.face == 0 || fd.face == 1) && fd.depth == size - 1)
				|| (use && fd.face == 3 && fd.depth == 1)
				|| (use && fd.face == 2 && fd.depth == 0)
				|| (!use && (fd.face == 0 || fd.face == 1) && fd.depth != size - 1)
				|| (!use && fd.face == 3 && fd.depth != 1)
				|| (!use && fd.face == 2 && fd.depth != 0)))
			|| (sticky && ((use && (fd.face == 0 || fd.face == 1) && fd.depth == size - 1)
				|| (use && fd.face == 3 && (fd.depth == 1 || fd.depth == 2))
				|| (use && fd.face == 2 && fd.depth == 0)
				|| (!use && (fd.face == 0 || fd.face == 1) && fd.depth != size - 1)
				|| (!use && fd.face == 3 && fd.depth != 1 && fd.depth != 2)
				|| (!use && fd.face == 2 && fd.depth != 0)))) {
			glPushMatrix();
			glTranslate(-s0 * FACET_LENGTH, -FACET_LENGTH, FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, k, -1, -1, -1);
			glPopMatrix();
		}
		/* 5 */
		if (all || (!sticky && ((use && fd.face != 1 && fd.depth == size - 1)
				|| (use && fd.face == 1 && fd.depth == size - 2)
				|| (!use && fd.face != 1 && fd.depth != size - 1)
				|| (!use && fd.face == 1 && fd.depth != size - 2)))
			|| (sticky && ((use && fd.face != 1 && fd.depth == size - 1)
				|| (use && fd.face == 1 && (fd.depth == 1 || fd.depth == 2))
				|| (!use && fd.face != 1 && fd.depth != size - 1)
				|| (!use && fd.face == 1 && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(FACET_LENGTH, -s0 * FACET_LENGTH, FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, 2, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && (fd.face == 2 || fd.face == 3) && fd.depth == size - 1)
				|| (use && fd.face == 0 && fd.depth == 1)
				|| (use && fd.face == 1 && fd.depth == 0)
				|| (!use && (fd.face == 2 || fd.face == 3) && fd.depth != size - 1)
				|| (!use && fd.face == 0 && fd.depth != 1)
				|| (!use && fd.face == 1 && fd.depth != 0)))
			|| (sticky && ((use && (fd.face == 2 || fd.face == 3) && fd.depth == size - 1)
				|| (use && fd.face == 0 && (fd.depth == 1 || fd.depth == 2))
				|| (use && fd.face == 1 && fd.depth == 0)
				|| (!use && (fd.face == 2 || fd.face == 3) && fd.depth != size - 1)
				|| (!use && fd.face == 0 && fd.depth != 1 && fd.depth != 2)
				|| (!use && fd.face == 1 && fd.depth != 0)))) {
			glPushMatrix();
			glTranslate(s0 * FACET_LENGTH, -FACET_LENGTH, FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, j, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && (fd.face == 0 || fd.face == 3) && fd.depth == size - 1)
				|| (use && fd.face == 2 && fd.depth == 1)
				|| (use && fd.face == 1 && fd.depth == 0)
				|| (!use && (fd.face == 0 || fd.face == 3) && fd.depth != size - 1)
				|| (!use && fd.face == 2 && fd.depth != 1)
				|| (!use && fd.face == 1 && fd.depth != 0)))
			|| (sticky && ((use && (fd.face == 0 || fd.face == 3) && fd.depth == size - 1)
				|| (use && fd.face == 2 && (fd.depth == 1 || fd.depth == 2))
				|| (use && fd.face == 1 && fd.depth == 0)
				|| (!use && (fd.face == 0 || fd.face == 3) && fd.depth != size - 1)
				|| (!use && fd.face == 2 && fd.depth != 1 && fd.depth != 2)
				|| (!use && fd.face == 1 && fd.depth != 0)))) {
			glPushMatrix();
			glTranslate(FACET_LENGTH, -FACET_LENGTH, s0 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, k, -1, -1);
			glPopMatrix();
		}
		/* 6 */
		if (all || (!sticky && ((use && fd.face != 0 && fd.depth == size - 1)
				|| (use && fd.face == 0 && fd.depth == size - 2)
				|| (!use && fd.face != 0 && fd.depth != size - 1)
				|| (!use && fd.face == 0 && fd.depth != size - 2)))
			|| (sticky && ((use && fd.face != 0 && fd.depth == size - 1)
				|| (use && fd.face == 0 && (fd.depth == 1 || fd.depth == 2))
				|| (!use && fd.face != 0 && fd.depth != size - 1)
				|| (!use && fd.face == 0 && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(FACET_LENGTH, -s0 * FACET_LENGTH, -FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, -1, 2, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && (fd.face == 1 || fd.face == 2) && fd.depth == size - 1)
				|| (use && fd.face == 3 && fd.depth == 1)
				|| (use && fd.face == 0 && fd.depth == 0)
				|| (!use && (fd.face == 1 || fd.face == 2) && fd.depth != size - 1)
				|| (!use && fd.face == 3 && fd.depth != 1)
				|| (!use && fd.face == 0 && fd.depth != 0)))
			|| (sticky && ((use && (fd.face == 1 || fd.face == 2) && fd.depth == size - 1)
				|| (use && fd.face == 3 && (fd.depth == 1 || fd.depth == 2))
				|| (use && fd.face == 0 && fd.depth == 0)
				|| (!use && (fd.face == 1 || fd.face == 2) && fd.depth != size - 1)
				|| (!use && fd.face == 3 && fd.depth != 1 && fd.depth != 2)
				|| (!use && fd.face == 0 && fd.depth != 0)))) {
			glPushMatrix();
			glTranslate(FACET_LENGTH, -FACET_LENGTH, -s0 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, -1, j, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && (fd.face == 2 || fd.face == 3) && fd.depth == size - 1)
				|| (use && fd.face == 1 && fd.depth == 1)
				|| (use && fd.face == 0 && fd.depth == 0)
				|| (!use && (fd.face == 2 || fd.face == 3) && fd.depth != size - 1)
				|| (!use && fd.face == 1 && fd.depth != 1)
				|| (!use && fd.face == 0 && fd.depth != 0)))
			|| (sticky && ((use && (fd.face == 2 || fd.face == 3) && fd.depth == size - 1)
				|| (use && fd.face == 1 && (fd.depth == 1 || fd.depth == 2))
				|| (use && fd.face == 0 && fd.depth == 0)
				|| (!use && (fd.face == 2 || fd.face == 3) && fd.depth != size - 1)
				|| (!use && fd.face == 1 && fd.depth != 1 && fd.depth != 2)
				|| (!use && fd.face == 0 && fd.depth != 0)))) {
			glPushMatrix();
			glTranslate(s0 * FACET_LENGTH, -FACET_LENGTH, -FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, -1, k, -1);
			glPopMatrix();
		}
		/* 7 */
		if (all || (!sticky && ((use && fd.face != 3 && fd.depth == size - 1)
				|| (use && fd.face == 3 && fd.depth == size - 2)
				|| (!use && fd.face != 3 && fd.depth != size - 1)
				|| (!use && fd.face == 3 && fd.depth != size - 2)))
			|| (sticky && ((use && fd.face != 3 && fd.depth == size - 1)
				|| (use && fd.face == 3 && (fd.depth == 1 || fd.depth == 2))
				|| (!use && fd.face != 3 && fd.depth != size - 1)
				|| (!use && fd.face == 3 && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(-FACET_LENGTH, -s0 * FACET_LENGTH, -FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, -1, -1, 2);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && (fd.face == 0 || fd.face == 1) && fd.depth == size - 1)
				|| (use && fd.face == 2 && fd.depth == 1)
				|| (use && fd.face == 3 && fd.depth == 0)
				|| (!use && (fd.face == 0 || fd.face == 1) && fd.depth != size - 1)
				|| (!use && fd.face == 2 && fd.depth != 1)
				|| (!use && fd.face == 3 && fd.depth != 0)))
			|| (sticky && ((use && (fd.face == 0 || fd.face == 1) && fd.depth == size - 1)
				|| (use && fd.face == 2 && (fd.depth == 1 || fd.depth == 2))
				|| (use && fd.face == 3 && fd.depth == 0)
				|| (!use && (fd.face == 0 || fd.face == 1) && fd.depth != size - 1)
				|| (!use && fd.face == 2 && fd.depth != 1 && fd.depth != 2)
				|| (!use && fd.face == 3 && fd.depth != 0)))) {
			glPushMatrix();
			glTranslate(-s0 * FACET_LENGTH, -FACET_LENGTH, -FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, -1, -1, j);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && (fd.face == 1 || fd.face == 2) && fd.depth == size - 1)
				|| (use && fd.face == 0 && fd.depth == 1)
				|| (use && fd.face == 3 && fd.depth == 0)
				|| (!use && (fd.face == 1 || fd.face == 2) && fd.depth != size - 1)
				|| (!use && fd.face == 0 && fd.depth != 1)
				|| (!use && fd.face == 3 && fd.depth != 0)))
			|| (sticky && ((use && (fd.face == 1 || fd.face == 2) && fd.depth == size - 1)
				|| (use && fd.face == 0 && (fd.depth == 1 || fd.depth == 2))
				|| (use && fd.face == 3 && fd.depth == 0)
				|| (!use && (fd.face == 1 || fd.face == 2) && fd.depth != size - 1)
				|| (!use && fd.face == 0 && fd.depth != 1 && fd.depth != 2)
				|| (!use && fd.face == 3 && fd.depth != 0)))) {
			glPushMatrix();
			glTranslate(-FACET_LENGTH, -FACET_LENGTH, -s0* FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, -1, -1, k);
			glPopMatrix();
		}
	}
	if (size > 2 && size % 2 == 1) {
		/* MIDDLE EDGES */ /* 1, 3, 6; 5, 7, 12; 4, 8, 20*/
		s1 = size - 1;
		i = (s1 / 2) * (s1 / 2);
		j = (s1 / 2 + 1) * (s1 / 2 + 1) - 1;
		k = size * size - size;
		if (all || (use && (fd.face == 0 || fd.face == 1) && fd.depth == 0)
				|| (use && (fd.face == 2 || fd.face == 3) && fd.depth == s1 / 2)
				|| (!use && (fd.face == 0 || fd.face == 1) && fd.depth != 0)
				|| (!use && (fd.face == 2 || fd.face == 3) && fd.depth != s1 / 2)) {
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, s1 * FACET_LENGTH, 0);
			drawOctaFacet(w, i, j, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && (fd.face == 1 || fd.face == 2) && fd.depth == 0)
				|| (use && (fd.face == 0 || fd.face == 3) && fd.depth == s1 / 2)
				|| (!use && (fd.face == 1 || fd.face == 2) && fd.depth != 0)
				|| (!use && (fd.face == 0 || fd.face == 3) && fd.depth != s1 / 2)) {
			glPushMatrix();
			glTranslate(0, s1 * FACET_LENGTH, s1 * FACET_LENGTH);
			drawOctaFacet(w, -1, i, j, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && (fd.face == 2 || fd.face == 3) && fd.depth == 0)
				|| (use && (fd.face == 0 || fd.face == 1) && fd.depth == s1 / 2)
				|| (!use && (fd.face == 2 || fd.face == 3) && fd.depth != 0)
				|| (!use && (fd.face == 0 || fd.face == 1) && fd.depth != s1 / 2)) {
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, s1 * FACET_LENGTH, 0);
			drawOctaFacet(w, -1, -1, i, j, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && (fd.face == 0 || fd.face == 3) && fd.depth == 0)
				|| (use && (fd.face == 1 || fd.face == 2) && fd.depth == s1 / 2)
				|| (!use && (fd.face == 0 || fd.face == 3) && fd.depth != 0)
				|| (!use && (fd.face == 1 || fd.face == 2) && fd.depth != s1 / 2)) {
			glPushMatrix();
			glTranslate(0, s1 * FACET_LENGTH, -s1 * FACET_LENGTH);
			drawOctaFacet(w, j, -1, -1, i, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && (fd.face == 0 || fd.face == 3) && fd.depth == size - 1)
				|| (use && (fd.face == 1 || fd.face == 2) && fd.depth == s1 / 2)
				|| (!use && (fd.face == 0 || fd.face == 3) && fd.depth != size - 1)
				|| (!use && (fd.face == 1 || fd.face == 2) && fd.depth != s1 / 2)) {
			glPushMatrix();
			glTranslate(0, -s1 * FACET_LENGTH, s1 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, -1, -1, i, j, -1, -1);
			glPopMatrix();
		}
		if (all || (use && (fd.face == 2 || fd.face == 3) && fd.depth == size - 1)
				|| (use && (fd.face == 0 || fd.face == 1) && fd.depth == s1 / 2)
				|| (!use && (fd.face == 2 || fd.face == 3) && fd.depth != size - 1)
				|| (!use && (fd.face == 0 || fd.face == 1) && fd.depth != s1 / 2)) {
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, -s1 * FACET_LENGTH, 0);
			drawOctaFacet(w, -1, -1, -1, -1, -1, i, j, -1);
			glPopMatrix();
		}
		if (all || (use && (fd.face == 1 || fd.face == 2) && fd.depth == size - 1)
				|| (use && (fd.face == 0 || fd.face == 3) && fd.depth == s1 / 2)
				|| (!use && (fd.face == 1 || fd.face == 2) && fd.depth != size - 1)
				|| (!use && (fd.face == 0 || fd.face == 3) && fd.depth != s1 / 2)) {
			glPushMatrix();
			glTranslate(0, -s1 * FACET_LENGTH, -s1 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, -1, -1, -1, -1, i, j);
			glPopMatrix();
		}
		if (all || (use && (fd.face == 0 || fd.face == 1) && fd.depth == size - 1)
				|| (use && (fd.face == 2 || fd.face == 3) && fd.depth == s1 / 2)
				|| (!use && (fd.face == 0 || fd.face == 1) && fd.depth != size - 1)
				|| (!use && (fd.face == 2 || fd.face == 3) && fd.depth != s1 / 2)) {
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, -s1 * FACET_LENGTH, 0);
			drawOctaFacet(w, -1, -1, -1, -1, j, -1, -1, i);
			glPopMatrix();
		}
		if (all || (use && fd.face == 0 && fd.depth == 0)
				|| (use && (fd.face == 1 || fd.face == 3) && fd.depth == s1 / 2)
				|| (use && fd.face == 2 && fd.depth == size - 1)
				|| (!use && fd.face == 0 && fd.depth != 0)
				|| (!use && (fd.face == 1 || fd.face == 3) && fd.depth != s1 / 2)
				|| (!use && fd.face == 2 && fd.depth != size - 1)) {
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, 0, -s1 * FACET_LENGTH);
			drawOctaFacet(w, k, -1, -1, -1, -1, -1, k, -1);
			glPopMatrix();
		}
		if (all || (use && fd.face == 1 && fd.depth == 0)
				|| (use && (fd.face == 0 || fd.face == 2) && fd.depth == s1 / 2)
				|| (use && fd.face == 3 && fd.depth == size - 1)
				|| (!use && fd.face == 1 && fd.depth != 0)
				|| (!use && (fd.face == 0 || fd.face == 2) && fd.depth != s1 / 2)
				|| (!use && fd.face == 3 && fd.depth != size - 1)) {
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, 0, s1 * FACET_LENGTH);
			drawOctaFacet(w, -1, k, -1, -1, -1, k, -1, -1);
			glPopMatrix();
		}
		if (all || (use && fd.face == 2 && fd.depth == 0)
				|| (use && (fd.face == 1 || fd.face == 3) && fd.depth == s1 / 2)
				|| (use && fd.face == 0 && fd.depth == size - 1)
				|| (!use && fd.face == 2 && fd.depth != 0)
				|| (!use && (fd.face == 1 || fd.face == 3) && fd.depth != s1 / 2)
				|| (!use && fd.face == 0 && fd.depth != size - 1)) {
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, 0, s1 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, k, -1, k, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && fd.face == 3 && fd.depth == 0)
				|| (use && (fd.face == 0 || fd.face == 2) && fd.depth == s1 / 2)
				|| (use && fd.face == 1 && fd.depth == size - 1)
				|| (!use && fd.face == 3 && fd.depth != 0)
				|| (!use && (fd.face == 0 || fd.face == 2) && fd.depth != s1 / 2)
				|| (!use && fd.face == 1 && fd.depth != size - 1)) {
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, 0, -s1 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, -1, k, -1, -1, -1, k);
			glPopMatrix();
		}
	} else if (size > 2 && size % 2 == 0) {
		/* CENTER EDGES - 1 */ /* (5, 7, 12), */
		int m = size / 2;
		s1 = size - 1;
		i = (size / 2) * (size / 2) + 1;
		j = (size / 2 + 1) * (size / 2 + 1) - 2;
		k = size * size - size;
		/* 0 */
		if (all || (!sticky && ((use && (fd.face == 0 || fd.face == 1) && fd.depth == 0)
				|| (use && fd.face == 2 && fd.depth == m)
				|| (use && fd.face == 3 && fd.depth == m - 1)
				|| (!use && (fd.face == 0 || fd.face == 1) && fd.depth != 0)
				|| (!use && fd.face == 2 && fd.depth != m)
				|| (!use && fd.face == 3 && fd.depth != m - 1)))
			|| (sticky && ((use && (fd.face == 0 || fd.face == 1) && fd.depth == 0)
				|| (use && (fd.face == 2 || fd.face == 3) && (fd.depth == 1 || fd.depth == 2))
				|| (!use && (fd.face == 0 || fd.face == 1) && fd.depth != 0)
				|| (!use && (fd.face == 2 || fd.face == 3) && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, s1 * FACET_LENGTH, -FACET_LENGTH);
			drawTetraFacet(w, i, -1, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && (fd.face == 0 || fd.face == 3) && fd.depth == 0)
				|| (use && fd.face == 2 && fd.depth == m)
				|| (use && fd.face == 1 && fd.depth == m - 1)
				|| (!use && (fd.face == 0 || fd.face == 3) && fd.depth != 0)
				|| (!use && fd.face == 2 && fd.depth != m)
				|| (!use && fd.face == 1 && fd.depth != m - 1)))
			|| (sticky && ((use && (fd.face == 0 || fd.face == 3) && fd.depth == 0)
				|| (use && (fd.face == 1 || fd.face == 2) && (fd.depth == 1 || fd.depth == 2))
				|| (!use && (fd.face == 0 || fd.face == 3) && fd.depth != 0)
				|| (!use && (fd.face == 1 || fd.face == 2) && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(FACET_LENGTH, s1 * FACET_LENGTH, -s1 * FACET_LENGTH);
			drawTetraFacet(w, j, -1, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && fd.face == 0 && fd.depth == 0)
				|| (use && fd.face == 2 && fd.depth == size - 1)
				|| (use && (fd.face == 1 || fd.face == 3) && fd.depth == m - 1)
				|| (!use && fd.face == 0 && fd.depth != 0)
				|| (!use && fd.face == 2 && fd.depth != size - 1)
				|| (!use && (fd.face == 1 || fd.face == 3) && fd.depth != m - 1)))
			|| (sticky && ((use && fd.face == 0 && fd.depth == 0)
				|| (use && fd.face == 2 && fd.depth == size - 1)
				|| (use && (fd.face == 1 || fd.face == 3) && (fd.depth == 1 || fd.depth == 2))
				|| (!use && fd.face == 0 && fd.depth != 0)
				|| (!use && fd.face == 2 && fd.depth != size - 1)
				|| (!use && (fd.face == 1 || fd.face == 3) && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, FACET_LENGTH, -s1 * FACET_LENGTH);
			drawTetraFacet(w, k, -1, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		/* 1 */
		if (all || (!sticky && ((use && (fd.face == 1 || fd.face == 2) && fd.depth == 0)
				|| (use && fd.face == 3 && fd.depth == m)
				|| (use && fd.face == 0 && fd.depth == m - 1)
				|| (!use && (fd.face == 1 || fd.face == 2) && fd.depth != 0)
				|| (!use && fd.face == 3 && fd.depth != m)
				|| (!use && fd.face == 0 && fd.depth != m - 1)))
			|| (sticky && ((use && (fd.face == 1 || fd.face == 2) && fd.depth == 0)
				|| (use && (fd.face == 0 || fd.face == 3) && (fd.depth == 1 || fd.depth == 2))
				|| (!use && (fd.face == 1 || fd.face == 2) && fd.depth != 0)
				|| (!use && (fd.face == 0 || fd.face == 3) && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(FACET_LENGTH, s1 * FACET_LENGTH, s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, i, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && (fd.face == 0 || fd.face == 1) && fd.depth == 0)
				|| (use && fd.face == 3 && fd.depth == m)
				|| (use && fd.face == 2 && fd.depth == m - 1)
				|| (!use && (fd.face == 0 || fd.face == 1) && fd.depth != 0)
				|| (!use && fd.face == 3 && fd.depth != m)
				|| (!use && fd.face == 2 && fd.depth != m - 1)))
			|| (sticky && ((use && (fd.face == 0 || fd.face == 1) && fd.depth == 0)
				|| (use && (fd.face == 2 || fd.face == 3) && (fd.depth == 1 || fd.depth == 2))
				|| (!use && (fd.face == 0 || fd.face == 1) && fd.depth != 0)
				|| (!use && (fd.face == 2 || fd.face == 3) && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, s1 * FACET_LENGTH, FACET_LENGTH);
			drawTetraFacet(w, -1, j, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && fd.face == 1 && fd.depth == 0)
				|| (use && fd.face == 3 && fd.depth == size - 1)
				|| (use && (fd.face == 0 || fd.face == 2) && fd.depth == m - 1)
				|| (!use && fd.face == 1 && fd.depth != 0)
				|| (!use && fd.face == 3 && fd.depth != size - 1)
				|| (!use && (fd.face == 0 || fd.face == 2) && fd.depth != m - 1)))
			|| (sticky && ((use && fd.face == 1 && fd.depth == 0)
				|| (use && fd.face == 3 && fd.depth == size - 1)
				|| (use && (fd.face == 0 || fd.face == 2) && (fd.depth == 1 || fd.depth == 2))
				|| (!use && fd.face == 1 && fd.depth != 0)
				|| (!use && fd.face == 3 && fd.depth != size - 1)
				|| (!use && (fd.face == 0 || fd.face == 2) && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, FACET_LENGTH, s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, k, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		/* 2 */
		if (all || (!sticky && ((use && (fd.face == 2 || fd.face == 3) && fd.depth == 0)
				|| (use && fd.face == 0 && fd.depth == m)
				|| (use && fd.face == 1 && fd.depth == m - 1)
				|| (!use && (fd.face == 2 || fd.face == 3) && fd.depth != 0)
				|| (!use && fd.face == 0 && fd.depth != m)
				|| (!use && fd.face == 1 && fd.depth != m - 1)))
			|| (sticky && ((use && (fd.face == 2 || fd.face == 3) && fd.depth == 0)
				|| (use && (fd.face == 0 || fd.face == 1) && (fd.depth == 1 || fd.depth == 2))
				|| (!use && (fd.face == 2 || fd.face == 3) && fd.depth != 0)
				|| (!use && (fd.face == 0 || fd.face == 1) && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, s1 * FACET_LENGTH, FACET_LENGTH);
			drawTetraFacet(w, -1, -1, i, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && (fd.face == 1 || fd.face == 2) && fd.depth == 0)
				|| (use && fd.face == 0 && fd.depth == m)
				|| (use && fd.face == 3 && fd.depth == m - 1)
				|| (!use && (fd.face == 1 || fd.face == 2) && fd.depth != 0)
				|| (!use && fd.face == 0 && fd.depth != m)
				|| (!use && fd.face == 3 && fd.depth != m - 1)))
			|| (sticky && ((use && (fd.face == 1 || fd.face == 2) && fd.depth == 0)
				|| (use && (fd.face == 0 || fd.face == 3) && (fd.depth == 1 || fd.depth == 2))
				|| (!use && (fd.face == 1 || fd.face == 2) && fd.depth != 0)
				|| (!use && (fd.face == 0 || fd.face == 3) && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(-FACET_LENGTH, s1 * FACET_LENGTH, s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, j, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && fd.face == 2 && fd.depth == 0)
				|| (use && fd.face == 0 && fd.depth == size - 1)
				|| (use && (fd.face == 1 || fd.face == 3) && fd.depth == 1)
				|| (!use && fd.face == 2 && fd.depth != 0)
				|| (!use && fd.face == 0 && fd.depth != size - 1)
				|| (!use && (fd.face == 1 || fd.face == 3) && fd.depth != 1)))
			|| (sticky && ((use && fd.face == 2 && fd.depth == 0)
				|| (use && fd.face == 0 && fd.depth == size - 1)
				|| (use && (fd.face == 1 || fd.face == 3) && (fd.depth == 1 || fd.depth == 2))
				|| (!use && fd.face == 2 && fd.depth != 0)
				|| (!use && fd.face == 0 && fd.depth != size - 1)
				|| (!use && (fd.face == 1 || fd.face == 3) && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, FACET_LENGTH, s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, k, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		/* 3 */
		if (all || (!sticky && ((use && (fd.face == 0 || fd.face == 3) && fd.depth == 0)
				|| (use && fd.face == 1 && fd.depth == m)
				|| (use && fd.face == 2 && fd.depth == m - 1)
				|| (!use && (fd.face == 0 || fd.face == 3) && fd.depth != 0)
				|| (!use && fd.face == 1 && fd.depth != m)
				|| (!use && fd.face == 2 && fd.depth != m - 1)))
			|| (sticky && ((use && (fd.face == 0 || fd.face == 3) && fd.depth == 0)
				|| (use && (fd.face == 1 || fd.face == 2) && (fd.depth == 1 || fd.depth == 2))
				|| (!use && (fd.face == 0 || fd.face == 3) && fd.depth != 0)
				|| (!use && (fd.face == 1 || fd.face == 2) && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(-FACET_LENGTH, s1 * FACET_LENGTH, -s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, i, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && (fd.face == 2 || fd.face == 3) && fd.depth == 0)
				|| (use && fd.face == 1 && fd.depth == m)
				|| (use && fd.face == 0 && fd.depth == m - 1)
				|| (!use && (fd.face == 2 || fd.face == 3) && fd.depth != 0)
				|| (!use && fd.face == 1 && fd.depth != m)
				|| (!use && fd.face == 0 && fd.depth != m - 1)))
			|| (sticky && ((use && (fd.face == 2 || fd.face == 3) && fd.depth == 0)
				|| (use && (fd.face == 0 || fd.face == 1) && (fd.depth == 1 || fd.depth == 2))
				|| (!use && (fd.face == 2 || fd.face == 3) && fd.depth != 0)
				|| (!use && (fd.face == 0 || fd.face == 1) && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, s1 * FACET_LENGTH, -FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, j, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && fd.face == 3 && fd.depth == 0)
				|| (use && fd.face == 1 && fd.depth == size - 1)
				|| (use && (fd.face == 0 || fd.face == 2) && fd.depth == m - 1)
				|| (!use && fd.face == 3 && fd.depth != 0)
				|| (!use && fd.face == 1 && fd.depth != size - 1)
				|| (!use && (fd.face == 0 || fd.face == 2) && fd.depth != m - 1)))
			|| (sticky && ((use && fd.face == 3 && fd.depth == 0)
				|| (use && fd.face == 1 && fd.depth == size - 1)
				|| (use && (fd.face == 0 || fd.face == 2) && (fd.depth == 1 || fd.depth == 2))
				|| (!use && fd.face == 3 && fd.depth != 0)
				|| (!use && fd.face == 1 && fd.depth != size - 1)
				|| (!use && (fd.face == 0 || fd.face == 2) && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, FACET_LENGTH, -s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, k, -1, -1, -1, -1);
			glPopMatrix();
		}
		/* 4 */
		if (all || (!sticky && ((use && (fd.face == 0 || fd.face == 3) && fd.depth == size - 1)
				|| (use && fd.face == 1 && fd.depth == m)
				|| (use && fd.face == 2 && fd.depth == m - 1)
				|| (!use && (fd.face == 0 || fd.face == 3) && fd.depth != size - 1)
				|| (!use && fd.face == 1 && fd.depth != m)
				|| (!use && fd.face == 2 && fd.depth != m - 1)))
			|| (sticky && ((use && (fd.face == 0 || fd.face == 3) && fd.depth == size - 1)
				|| (use && (fd.face == 1 || fd.face == 2) && (fd.depth == 1 || fd.depth == 2))
				|| (!use && (fd.face == 0 || fd.face == 3) && fd.depth != size - 1)
				|| (!use && (fd.face == 1 || fd.face == 2) && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(-FACET_LENGTH, -s1 * FACET_LENGTH, s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, i, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && (fd.face == 0 || fd.face == 1) && fd.depth == size - 1)
				|| (use && fd.face == 3 && fd.depth == m)
				|| (use && fd.face == 2 && fd.depth == m - 1)
				|| (!use && (fd.face == 0 || fd.face == 1) && fd.depth != size - 1)
				|| (!use && fd.face == 3 && fd.depth != m)
				|| (!use && fd.face == 2 && fd.depth != m - 1)))
			|| (sticky && ((use && (fd.face == 0 || fd.face == 1) && fd.depth == size - 1)
				|| (use && (fd.face == 2 || fd.face == 3) && (fd.depth == 1 || fd.depth == 2))
				|| (!use && (fd.face == 0 || fd.face == 1) && fd.depth != size - 1)
				|| (!use && (fd.face == 2 || fd.face == 3) && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, -s1 * FACET_LENGTH, FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, j, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && fd.face == 0 && fd.depth == size - 1)
				|| (use && fd.face == 2 && fd.depth == 0)
				|| (use && (fd.face == 1 || fd.face == 3) && fd.depth == m)
				|| (!use && fd.face == 0 && fd.depth != size - 1)
				|| (!use && fd.face == 2 && fd.depth != 0)
				|| (!use && (fd.face == 1 || fd.face == 3) && fd.depth != m)))
			|| (sticky && ((use && fd.face == 0 && fd.depth == size - 1)
				|| (use && fd.face == 2 && fd.depth == 0)
				|| (use && (fd.face == 1 || fd.face == 3) && (fd.depth == 1 || fd.depth == 2))
				|| (!use && fd.face == 0 && fd.depth != size - 1)
				|| (!use && fd.face == 2 && fd.depth != 0)
				|| (!use && (fd.face == 1 || fd.face == 3) && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, -FACET_LENGTH, s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, k, -1, -1, -1);
			glPopMatrix();
		}
		/* 5 */
		if (all || (!sticky && ((use && (fd.face == 2 || fd.face == 3) && fd.depth == size - 1)
				|| (use && fd.face == 0 && fd.depth == m)
				|| (use && fd.face == 1 && fd.depth == m - 1)
				|| (!use && (fd.face == 2 || fd.face == 3) && fd.depth != size - 1)
				|| (!use && fd.face == 0 && fd.depth != m)
				|| (!use && fd.face == 1 && fd.depth != m - 1)))
			|| (sticky && ((use && (fd.face == 2 || fd.face == 3) && fd.depth == size - 1)
				|| (use && (fd.face == 0 || fd.face == 1) && (fd.depth == 1 || fd.depth == 2))
				|| (!use && (fd.face == 2 || fd.face == 3) && fd.depth != size - 1)
				|| (!use && (fd.face == 0 || fd.face == 1) && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, -s1 * FACET_LENGTH, FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, i, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && (fd.face == 0 || fd.face == 3) && fd.depth == size - 1)
				|| (use && fd.face == 2 && fd.depth == m)
				|| (use && fd.face == 1 && fd.depth == m - 1)
				|| (!use && (fd.face == 0 || fd.face == 3) && fd.depth != size - 1)
				|| (!use && fd.face == 2 && fd.depth != m)
				|| (!use && fd.face == 1 && fd.depth != m - 1)))
			|| (sticky && ((use && (fd.face == 0 || fd.face == 3) && fd.depth == size - 1)
				|| (use && (fd.face == 1 || fd.face == 2) && (fd.depth == 1 || fd.depth == 2))
				|| (!use && (fd.face == 0 || fd.face == 3) && fd.depth != size - 1)
				|| (!use && (fd.face == 1 || fd.face == 2) && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(FACET_LENGTH, -s1 * FACET_LENGTH, s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, j, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && fd.face == 3 && fd.depth == size - 1)
				|| (use && fd.face == 1 && fd.depth == 0)
				|| (use && (fd.face == 0 || fd.face == 2) && fd.depth == m)
				|| (!use && fd.face == 3 && fd.depth != size - 1)
				|| (!use && fd.face == 1 && fd.depth != 0)
				|| (!use && (fd.face == 0 || fd.face == 2) && fd.depth != m)))
			|| (sticky && ((use && fd.face == 3 && fd.depth == size - 1)
				|| (use && fd.face == 1 && fd.depth == 0)
				|| (use && (fd.face == 0 || fd.face == 2) && (fd.depth == 1 || fd.depth == 2))
				|| (!use && fd.face == 3 && fd.depth != size - 1)
				|| (!use && fd.face == 1 && fd.depth != 0)
				|| (!use && (fd.face == 0 || fd.face == 2) && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, -FACET_LENGTH, s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, k, -1, -1);
			glPopMatrix();
		}
		/* 6 */
		if (all || (!sticky && ((use && (fd.face == 1 || fd.face == 2) && fd.depth == size - 1)
				|| (use && fd.face == 3 && fd.depth == m)
				|| (use && fd.face == 0 && fd.depth == m - 1)
				|| (!use && (fd.face == 1 || fd.face == 2) && fd.depth != size - 1)
				|| (!use && fd.face == 3 && fd.depth != m)
				|| (!use && fd.face == 0 && fd.depth != m - 1)))
			|| (sticky && ((use && (fd.face == 1 || fd.face == 2) && fd.depth == size - 1)
				|| (use && (fd.face == 0 || fd.face == 3) && (fd.depth == 1 || fd.depth == 2))
				|| (!use && (fd.face == 1 || fd.face == 2) && fd.depth != size - 1)
				|| (!use && (fd.face == 0 || fd.face == 3) && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(FACET_LENGTH, -s1 * FACET_LENGTH, -s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, -1, i, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && (fd.face == 2 || fd.face == 3) && fd.depth == size - 1)
				|| (use && fd.face == 1 && fd.depth == m)
				|| (use && fd.face == 0 && fd.depth == m - 1)
				|| (!use && (fd.face == 2 || fd.face == 3) && fd.depth != size - 1)
				|| (!use && fd.face == 1 && fd.depth != m)
				|| (!use && fd.face == 0 && fd.depth != m - 1)))
			|| (sticky && ((use && (fd.face == 2 || fd.face == 3) && fd.depth == size - 1)
				|| (use && (fd.face == 0 || fd.face == 1) && (fd.depth == 1 || fd.depth == 2))
				|| (!use && (fd.face == 2 || fd.face == 3) && fd.depth != size - 1)
				|| (!use && (fd.face == 0 || fd.face == 1) && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, -s1 * FACET_LENGTH, -FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, -1, j, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && fd.face == 2 && fd.depth == size - 1)
				|| (use && fd.face == 0 && fd.depth == 0)
				|| (use && (fd.face == 1 || fd.face == 3) && fd.depth == m)
				|| (!use && fd.face == 2 && fd.depth != size - 1)
				|| (!use && fd.face == 0 && fd.depth != 0)
				|| (!use && (fd.face == 1 || fd.face == 3) && fd.depth != m)))
			|| (sticky && ((use && fd.face == 2 && fd.depth == size - 1)
				|| (use && fd.face == 0 && fd.depth == 0)
				|| (use && (fd.face == 1 || fd.face == 3) && (fd.depth == 1 || fd.depth == 2))
				|| (!use && fd.face == 2 && fd.depth != size - 1)
				|| (!use && fd.face == 0 && fd.depth != 0)
				|| (!use && (fd.face == 1 || fd.face == 3) && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, -FACET_LENGTH, -s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, -1, k, -1);
			glPopMatrix();
		}
		/* 7 */
		if (all || (!sticky && ((use && (fd.face == 0 || fd.face == 1) && fd.depth == size - 1)
				|| (use && fd.face == 2 && fd.depth == m)
				|| (use && fd.face == 3 && fd.depth == m - 1)
				|| (!use && (fd.face == 0 || fd.face == 1) && fd.depth != size - 1)
				|| (!use && fd.face == 2 && fd.depth != m)
				|| (!use && fd.face == 3 && fd.depth != m - 1)))
			|| (sticky && ((use && (fd.face == 0 || fd.face == 1) && fd.depth == size - 1)
				|| (use && (fd.face == 2 || fd.face == 3) && (fd.depth == 1 || fd.depth == 2))
				|| (!use && (fd.face == 0 || fd.face == 1) && fd.depth != size - 1)
				|| (!use && (fd.face == 2 || fd.face == 3) && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, -s1 * FACET_LENGTH, -FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, -1, -1, i);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && (fd.face == 1 || fd.face == 2) && fd.depth == size - 1)
				|| (use && fd.face == 0 && fd.depth == m)
				|| (use && fd.face == 3 && fd.depth == m - 1)
				|| (!use && (fd.face == 1 || fd.face == 2) && fd.depth != size - 1)
				|| (!use && fd.face == 0 && fd.depth != m)
				|| (!use && fd.face == 3 && fd.depth != m - 1)))
			|| (sticky && ((use && (fd.face == 1 || fd.face == 2) && fd.depth == size - 1)
				|| (use && (fd.face == 0 || fd.face == 3) && (fd.depth == 1 || fd.depth == 2))
				|| (!use && (fd.face == 1 || fd.face == 2) && fd.depth != size - 1)
				|| (!use && (fd.face == 0 || fd.face == 3) && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(-FACET_LENGTH, -s1 * FACET_LENGTH, -s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, -1, -1, j);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && fd.face == 1 && fd.depth == size - 1)
				|| (use && fd.face == 3 && fd.depth == 0)
				|| (use && (fd.face == 0 || fd.face == 2) && fd.depth == m)
				|| (!use && fd.face == 1 && fd.depth != size - 1)
				|| (!use && fd.face == 3 && fd.depth != 0)
				|| (!use && (fd.face == 0 || fd.face == 2) && fd.depth != m)))
			|| (sticky && ((use && fd.face == 1 && fd.depth == size - 1)
				|| (use && fd.face == 3 && fd.depth == 0)
				|| (use && (fd.face == 0 || fd.face == 2) && (fd.depth == 1 || fd.depth == 2))
				|| (!use && fd.face == 1 && fd.depth != size - 1)
				|| (!use && fd.face == 3 && fd.depth != 0)
				|| (!use && (fd.face == 0 || fd.face == 2) && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, -FACET_LENGTH, -s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, -1, -1, k);
			glPopMatrix();
		}
	}
	if (size > 3) { /* EDGE 1 */
		int a, b, c, d, e, f;
		int s3 = size - 2;
		s1 = size - 1;
		s2 = 2;
		s0 = 2 * size - 4;
		a = 1;
		b = 3;
		c = s3 * s3;
		d = s1 * s1 - 1;
		e = s1 * s1 + 2;
		f = size * size - 3;
		if (all || (!sticky && ((use && (fd.face == 0 || fd.face == 1) && fd.depth == 0)
				|| (use && (fd.face == 2 || fd.face == 3) && fd.depth == 1)
				|| (!use && (fd.face == 0 || fd.face == 1) && fd.depth != 0)
				|| (!use && (fd.face == 2 || fd.face == 3) && fd.depth != 1)))
			|| (sticky && ((use && (fd.face == 0 || fd.face == 1) && fd.depth == 0)
				|| (use && (fd.face == 2 || fd.face == 3) && (fd.depth == 1 || fd.depth == 2))
				|| (!use && (fd.face == 0 || fd.face == 1) && fd.depth != 0)
				|| (!use && (fd.face == 2 || fd.face == 3) && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(s2 * FACET_LENGTH, s0 * FACET_LENGTH, 0);
			drawOctaFacet(w, a, b, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && (fd.face == 1 || fd.face == 2) && fd.depth == 0)
				|| (use && (fd.face == 0 || fd.face == 3) && fd.depth == 1)
				|| (!use && (fd.face == 1 || fd.face == 2) && fd.depth != 0)
				|| (!use && (fd.face == 0 || fd.face == 3) && fd.depth != 1)))
			|| (sticky && ((use && (fd.face == 1 || fd.face == 2) && fd.depth == 0)
				|| (use && (fd.face == 0 || fd.face == 3) && (fd.depth == 1 || fd.depth == 2))
				|| (!use && (fd.face == 1 || fd.face == 2) && fd.depth != 0)
				|| (!use && (fd.face == 0 || fd.face == 3) && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(0, s0 * FACET_LENGTH, s2 * FACET_LENGTH);
			drawOctaFacet(w, -1, a, b, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && (fd.face == 2 || fd.face == 3) && fd.depth == 0)
				|| (use && (fd.face == 0 || fd.face == 1) && fd.depth == 1)
				|| (!use && (fd.face == 2 || fd.face == 3) && fd.depth != 0)
				|| (!use && (fd.face == 0 || fd.face == 1) && fd.depth != 1)))
			|| (sticky && ((use && (fd.face == 2 || fd.face == 3) && fd.depth == 0)
				|| (use && (fd.face == 0 || fd.face == 1) && (fd.depth == 1 || fd.depth == 2))
				|| (!use && (fd.face == 2 || fd.face == 3) && fd.depth != 0)
				|| (!use && (fd.face == 0 || fd.face == 1) && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(-s2 * FACET_LENGTH, s0 * FACET_LENGTH, 0);
			drawOctaFacet(w, -1, -1, a, b, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && (fd.face == 0 || fd.face == 3) && fd.depth == 0)
				|| (use && (fd.face == 1 || fd.face == 2) && fd.depth == 1)
				|| (!use && (fd.face == 0 || fd.face == 3) && fd.depth != 0)
				|| (!use && (fd.face == 1 || fd.face == 2) && fd.depth != 1)))
			|| (sticky && ((use && (fd.face == 0 || fd.face == 3) && fd.depth == 0)
				|| (use && (fd.face == 1 || fd.face == 2) && (fd.depth == 1 || fd.depth == 2))
				|| (!use && (fd.face == 0 || fd.face == 3) && fd.depth != 0)
				|| (!use && (fd.face == 1 || fd.face == 2) && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(0, s0 * FACET_LENGTH, -s2 * FACET_LENGTH);
			drawOctaFacet(w, b, -1, -1, a, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && (fd.face == 0 || fd.face == 3) && fd.depth == size - 1)
				|| (use && (fd.face == 1 || fd.face == 2) && fd.depth == size - 2)
				|| (!use && (fd.face == 0 || fd.face == 3) && fd.depth != size - 1)
				|| (!use && (fd.face == 1 || fd.face == 2) && fd.depth != size - 2)))
			|| (sticky && ((use && (fd.face == 0 || fd.face == 3) && fd.depth == size - 1)
				|| (use && (fd.face == 1 || fd.face == 2) && (fd.depth == 1 || fd.depth == 2))
				|| (!use && (fd.face == 0 || fd.face == 3) && fd.depth != size - 1)
				|| (!use && (fd.face == 1 || fd.face == 2) && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(0, -s0 * FACET_LENGTH, s2 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, -1, -1, a, b, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && (fd.face == 2 || fd.face == 3) && fd.depth == size - 1)
				|| (use && (fd.face == 0 || fd.face == 1) && fd.depth == size - 2)
				|| (!use && (fd.face == 2 || fd.face == 3) && fd.depth != size - 1)
				|| (!use && (fd.face == 0 || fd.face == 1) && fd.depth != size - 2)))
			|| (sticky && ((use && (fd.face == 2 || fd.face == 3) && fd.depth == size - 1)
				|| (use && (fd.face == 0 || fd.face == 1) && (fd.depth == 1 || fd.depth == 2))
				|| (!use && (fd.face == 2 || fd.face == 3) && fd.depth != size - 1)
				|| (!use && (fd.face == 0 || fd.face == 1) && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(s2 * FACET_LENGTH, -s0 * FACET_LENGTH, 0);
			drawOctaFacet(w, -1, -1, -1, -1, -1, a, b, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && (fd.face == 1 || fd.face == 2) && fd.depth == size - 1)
				|| (use && (fd.face == 0 || fd.face == 3) && fd.depth == size - 2)
				|| (!use && (fd.face == 1 || fd.face == 2) && fd.depth != size - 1)
				|| (!use && (fd.face == 0 || fd.face == 3) && fd.depth != size - 2)))
			|| (sticky && ((use && (fd.face == 1 || fd.face == 2) && fd.depth == size - 1)
				|| (use && (fd.face == 0 || fd.face == 3) && (fd.depth == 1 || fd.depth == 2))
				|| (!use && (fd.face == 1 || fd.face == 2) && fd.depth != size - 1)
				|| (!use && (fd.face == 0 || fd.face == 3) && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(0, -s0 * FACET_LENGTH, -s2 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, -1, -1, -1, -1, a, b);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && (fd.face == 0 || fd.face == 1) && fd.depth == size - 1)
				|| (use && (fd.face == 2 || fd.face == 3) && fd.depth == size - 2)
				|| (!use && (fd.face == 0 || fd.face == 1) && fd.depth != size - 1)
				|| (!use && (fd.face == 2 || fd.face == 3) && fd.depth != size - 2)))
			|| (sticky && ((use && (fd.face == 0 || fd.face == 1) && fd.depth == size - 1)
				|| (use && (fd.face == 2 || fd.face == 3) && (fd.depth == 1 || fd.depth == 2))
				|| (!use && (fd.face == 0 || fd.face == 1) && fd.depth != size - 1)
				|| (!use && (fd.face == 2 || fd.face == 3) && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(-s2 * FACET_LENGTH, -s0 * FACET_LENGTH, 0);
			drawOctaFacet(w, -1, -1, -1, -1, b, -1, -1, a);
			glPopMatrix();
		}

		if (all || (!sticky && ((use && (fd.face == 0 || fd.face == 1) && fd.depth == 0)
				|| (use && (fd.face == 2 || fd.face == 3) && fd.depth == size - 2)
				|| (!use && (fd.face == 0 || fd.face == 1) && fd.depth != 0)
				|| (!use && (fd.face == 2 || fd.face == 3) && fd.depth != size - 2)))
			|| (sticky && ((use && (fd.face == 0 || fd.face == 1) && fd.depth == 0)
				|| (use && (fd.face == 2 || fd.face == 3) && (fd.depth == 1 || fd.depth == 2))
				|| (!use && (fd.face == 0 || fd.face == 1) && fd.depth != 0)
				|| (!use && (fd.face == 2 || fd.face == 3) && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(s0 * FACET_LENGTH, s2 * FACET_LENGTH, 0);
			drawOctaFacet(w, c, d, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && (fd.face == 1 || fd.face == 2) && fd.depth == 0)
				|| (use && (fd.face == 0 || fd.face == 3) && fd.depth == size - 2)
				|| (!use && (fd.face == 1 || fd.face == 2) && fd.depth != 0)
				|| (!use && (fd.face == 0 || fd.face == 3) && fd.depth != size - 2)))
			|| (sticky && ((use && (fd.face == 1 || fd.face == 2) && fd.depth == 0)
				|| (use && (fd.face == 0 || fd.face == 3) && (fd.depth == 1 || fd.depth == 2))
				|| (!use && (fd.face == 1 || fd.face == 2) && fd.depth != 0)
				|| (!use && (fd.face == 0 || fd.face == 3) && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(0, s2 * FACET_LENGTH, s0 * FACET_LENGTH);
			drawOctaFacet(w, -1, c, d, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && (fd.face == 2 || fd.face == 3) && fd.depth == 0)
				|| (use && (fd.face == 0 || fd.face == 1) && fd.depth == size - 2)
				|| (!use && (fd.face == 2 || fd.face == 3) && fd.depth != 0)
				|| (!use && (fd.face == 0 || fd.face == 1) && fd.depth != size - 2)))
			|| (sticky && ((use && (fd.face == 2 || fd.face == 3) && fd.depth == 0)
				|| (use && (fd.face == 0 || fd.face == 1) && (fd.depth == 1 || fd.depth == 2))
				|| (!use && (fd.face == 2 || fd.face == 3) && fd.depth != 0)
				|| (!use && (fd.face == 0 || fd.face == 1) && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(-s0 * FACET_LENGTH, s2 * FACET_LENGTH, 0);
			drawOctaFacet(w, -1, -1, c, d, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && (fd.face == 0 || fd.face == 3) && fd.depth == 0)
				|| (use && (fd.face == 1 || fd.face == 2) && fd.depth == size - 2)
				|| (!use && (fd.face == 0 || fd.face == 3) && fd.depth != 0)
				|| (!use && (fd.face == 1 || fd.face == 2) && fd.depth != size - 2)))
			|| (sticky && ((use && (fd.face == 0 || fd.face == 3) && fd.depth == 0)
				|| (use && (fd.face == 1 || fd.face == 2) && (fd.depth == 1 || fd.depth == 2))
				|| (!use && (fd.face == 0 || fd.face == 3) && fd.depth != 0)
				|| (!use && (fd.face == 1 || fd.face == 2) && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(0, s2 * FACET_LENGTH, -s0 * FACET_LENGTH);
			drawOctaFacet(w, d, -1, -1, c, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && (fd.face == 0 || fd.face == 3) && fd.depth == size - 1)
				|| (use && (fd.face == 1 || fd.face == 2) && fd.depth == 1)
				|| (!use && (fd.face == 0 || fd.face == 3) && fd.depth != size - 1)
				|| (!use && (fd.face == 1 || fd.face == 2) && fd.depth != 1)))
			|| (sticky && ((use && (fd.face == 0 || fd.face == 3) && fd.depth == size - 1)
				|| (use && (fd.face == 1 || fd.face == 2) && (fd.depth == 1 || fd.depth == 2))
				|| (!use && (fd.face == 0 || fd.face == 3) && fd.depth != size - 1)
				|| (!use && (fd.face == 1 || fd.face == 2) && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(0, -s2 * FACET_LENGTH, s0 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, -1, -1, c, d, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && (fd.face == 2 || fd.face == 3) && fd.depth == size - 1)
				|| (use && (fd.face == 0 || fd.face == 1) && fd.depth == 1)
				|| (!use && (fd.face == 2 || fd.face == 3) && fd.depth != size - 1)
				|| (!use && (fd.face == 0 || fd.face == 1) && fd.depth != 1)))
			|| (sticky && ((use && (fd.face == 2 || fd.face == 3) && fd.depth == size - 1)
				|| (use && (fd.face == 0 || fd.face == 1) && (fd.depth == 1 || fd.depth == 2))
				|| (!use && (fd.face == 2 || fd.face == 3) && fd.depth != size - 1)
				|| (!use && (fd.face == 0 || fd.face == 1) && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(s0 * FACET_LENGTH, -s2 * FACET_LENGTH, 0);
			drawOctaFacet(w, -1, -1, -1, -1, -1, c, d, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && (fd.face == 1 || fd.face == 2) && fd.depth == size - 1)
				|| (use && (fd.face == 0 || fd.face == 3) && fd.depth == 1)
				|| (!use && (fd.face == 1 || fd.face == 2) && fd.depth != size - 1)
				|| (!use && (fd.face == 0 || fd.face == 3) && fd.depth != 1)))
			|| (sticky && ((use && (fd.face == 1 || fd.face == 2) && fd.depth == size - 1)
				|| (use && (fd.face == 0 || fd.face == 3) && (fd.depth == 1 || fd.depth == 2))
				|| (!use && (fd.face == 1 || fd.face == 2) && fd.depth != size - 1)
				|| (!use && (fd.face == 0 || fd.face == 3) && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(0, -s2 * FACET_LENGTH, -s0 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, -1, -1, -1, -1, c, d);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && (fd.face == 0 || fd.face == 1) && fd.depth == size - 1)
				|| (use && (fd.face == 2 || fd.face == 3) && fd.depth == 1)
				|| (!use && (fd.face == 0 || fd.face == 1) && fd.depth != size - 1)
				|| (!use && (fd.face == 2 || fd.face == 3) && fd.depth != 1)))
			|| (sticky && ((use && (fd.face == 0 || fd.face == 1) && fd.depth == size - 1)
				|| (use && (fd.face == 2 || fd.face == 3) && (fd.depth == 1 || fd.depth == 2))
				|| (!use && (fd.face == 0 || fd.face == 1) && fd.depth != size - 1)
				|| (!use && (fd.face == 2 || fd.face == 3) && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(-s0 * FACET_LENGTH, -s2 * FACET_LENGTH, 0);
			drawOctaFacet(w, -1, -1, -1, -1, d, -1, -1, c);
			glPopMatrix();
		}

		if (all || (!sticky && ((use && fd.face == 0 && fd.depth == 0)
				|| (use && fd.face == 2 && fd.depth == size - 1)
				|| (use && fd.face == 1 && fd.depth == 1)
				|| (use && fd.face == 3 && fd.depth == size - 2)
				|| (!use && fd.face == 0 && fd.depth != 0)
				|| (!use && fd.face == 2 && fd.depth != size - 1)
				|| (!use && fd.face == 1 && fd.depth != 1)
				|| (!use && fd.face == 3 && fd.depth != size - 2)))
			|| (sticky && ((use && fd.face == 0 && fd.depth == 0)
				|| (use && fd.face == 2 && fd.depth == size - 1)
				|| (use && (fd.face == 1 || fd.face == 3) && (fd.depth == 1 || fd.depth == 2))
				|| (!use && fd.face == 0 && fd.depth != 0)
				|| (!use && fd.face == 2 && fd.depth != size - 1)
				|| (!use && (fd.face == 1 || fd.face == 3) && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(s0 * FACET_LENGTH, 0, -s2 * FACET_LENGTH);
			drawOctaFacet(w, e, -1, -1, -1, -1, -1, f, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && fd.face == 1 && fd.depth == 0)
				|| (use && fd.face == 3 && fd.depth == size - 1)
				|| (use && fd.face == 2 && fd.depth == 1)
				|| (use && fd.face == 0 && fd.depth == size - 2)
				|| (!use && fd.face == 1 && fd.depth != 0)
				|| (!use && fd.face == 3 && fd.depth != size - 1)
				|| (!use && fd.face == 2 && fd.depth != 1)
				|| (!use && fd.face == 0 && fd.depth != size - 2)))
			|| (sticky && ((use && fd.face == 1 && fd.depth == 0)
				|| (use && fd.face == 3 && fd.depth == size - 1)
				|| (use && (fd.face == 0 || fd.face == 2) && (fd.depth == 1 || fd.depth == 2))
				|| (!use && fd.face == 1 && fd.depth != 0)
				|| (!use && fd.face == 3 && fd.depth != size - 1)
				|| (!use && (fd.face == 0 || fd.face == 2) && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(s2 * FACET_LENGTH, 0, s0 * FACET_LENGTH);
			drawOctaFacet(w, -1, e, -1, -1, -1, f, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && fd.face == 2 && fd.depth == 0)
				|| (use && fd.face == 0 && fd.depth == size - 1)
				|| (use && fd.face == 3 && fd.depth == 1)
				|| (use && fd.face == 1 && fd.depth == size - 2)
				|| (!use && fd.face == 2 && fd.depth != 0)
				|| (!use && fd.face == 0 && fd.depth != size - 1)
				|| (!use && fd.face == 3 && fd.depth != 1)
				|| (!use && fd.face == 1 && fd.depth != size - 2)))
			|| (sticky && ((use && fd.face == 2 && fd.depth == 0)
				|| (use && fd.face == 0 && fd.depth == size - 1)
				|| (use && (fd.face == 1 || fd.face == 3) && (fd.depth == 1 || fd.depth == 2))
				|| (!use && fd.face == 2 && fd.depth != 0)
				|| (!use && fd.face == 0 && fd.depth != size - 1)
				|| (!use && (fd.face == 1 || fd.face == 3) && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(-s0 * FACET_LENGTH, 0, s2 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, e, -1, f, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && fd.face == 3 && fd.depth == 0)
				|| (use && fd.face == 1 && fd.depth == size - 1)
				|| (use && fd.face == 0 && fd.depth == 1)
				|| (use && fd.face == 2 && fd.depth == size - 2)
				|| (!use && fd.face == 3 && fd.depth != 0)
				|| (!use && fd.face == 1 && fd.depth != size - 1)
				|| (!use && fd.face == 0 && fd.depth != 1)
				|| (!use && fd.face == 2 && fd.depth != size - 2)))
			|| (sticky && ((use && fd.face == 3 && fd.depth == 0)
				|| (use && fd.face == 1 && fd.depth == size - 1)
				|| (use && (fd.face == 0 || fd.face == 2) && (fd.depth == 1 || fd.depth == 2))
				|| (!use && fd.face == 3 && fd.depth != 0)
				|| (!use && fd.face == 1 && fd.depth != size - 1)
				|| (!use && (fd.face == 0 || fd.face == 2) && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(-s2 * FACET_LENGTH, 0, -s0 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, -1, e, -1, -1, -1, f);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && fd.face == 2 && fd.depth == 0)
				|| (use && fd.face == 0 && fd.depth == size - 1)
				|| (use && fd.face == 1 && fd.depth == 1)
				|| (use && fd.face == 3 && fd.depth == size - 2)
				|| (!use && fd.face == 2 && fd.depth != 0)
				|| (!use && fd.face == 0 && fd.depth != size - 1)
				|| (!use && fd.face == 1 && fd.depth != 1)
				|| (!use && fd.face == 3 && fd.depth != size - 2)))
			|| (sticky && ((use && fd.face == 2 && fd.depth == 0)
				|| (use && fd.face == 0 && fd.depth == size - 1)
				|| (use && (fd.face == 1 || fd.face == 3) && (fd.depth == 1 || fd.depth == 2))
				|| (!use && fd.face == 2 && fd.depth != 0)
				|| (!use && fd.face == 0 && fd.depth != size - 1)
				|| (!use && (fd.face == 1 || fd.face == 3) && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(-s2 * FACET_LENGTH, 0, s0 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, f, -1, e, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && fd.face == 1 && fd.depth == 0)
				|| (use && fd.face == 3 && fd.depth == size - 1)
				|| (use && fd.face == 0 && fd.depth == 1)
				|| (use && fd.face == 2 && fd.depth == size - 2)
				|| (!use && fd.face == 1 && fd.depth != 0)
				|| (!use && fd.face == 3 && fd.depth != size - 1)
				|| (!use && fd.face == 0 && fd.depth != 1)
				|| (!use && fd.face == 2 && fd.depth != size - 2)))
			|| (sticky && ((use && fd.face == 1 && fd.depth == 0)
				|| (use && fd.face == 3 && fd.depth == size - 1)
				|| (use && (fd.face == 0 || fd.face == 2) && (fd.depth == 1 || fd.depth == 2))
				|| (!use && fd.face == 1 && fd.depth != 0)
				|| (!use && fd.face == 3 && fd.depth != size - 1)
				|| (!use && (fd.face == 0 || fd.face == 2) && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(s0 * FACET_LENGTH, 0, s2 * FACET_LENGTH);
			drawOctaFacet(w, -1, f, -1, -1, -1, e, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && fd.face == 0 && fd.depth == 0)
				|| (use && fd.face == 2 && fd.depth == size - 1)
				|| (use && fd.face == 3 && fd.depth == 1)
				|| (use && fd.face == 1 && fd.depth == size - 2)
				|| (!use && fd.face == 0 && fd.depth != 0)
				|| (!use && fd.face == 2 && fd.depth != size - 1)
				|| (!use && fd.face == 3 && fd.depth != 1)
				|| (!use && fd.face == 1 && fd.depth != size - 2)))
			|| (sticky && ((use && fd.face == 0 && fd.depth == 0)
				|| (use && fd.face == 2 && fd.depth == size - 1)
				|| (use && (fd.face == 1 || fd.face == 3) && (fd.depth == 1 || fd.depth == 2))
				|| (!use && fd.face == 0 && fd.depth != 0)
				|| (!use && fd.face == 2 && fd.depth != size - 1)
				|| (!use && (fd.face == 1 || fd.face == 3) && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(s2 * FACET_LENGTH, 0, -s0 * FACET_LENGTH);
			drawOctaFacet(w, f, -1, -1, -1, -1, -1, e, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && fd.face == 3 && fd.depth == 0)
				|| (use && fd.face == 1 && fd.depth == size - 1)
				|| (use && fd.face == 2 && fd.depth == 1)
				|| (use && fd.face == 0 && fd.depth == size - 2)
				|| (!use && fd.face == 3 && fd.depth != 0)
				|| (!use && fd.face == 1 && fd.depth != size - 1)
				|| (!use && fd.face == 2 && fd.depth != 1)
				|| (!use && fd.face == 0 && fd.depth != size - 2)))
			|| (sticky && ((use && fd.face == 3 && fd.depth == 0)
				|| (use && fd.face == 1 && fd.depth == size - 1)
				|| (use && (fd.face == 0 || fd.face == 2) && (fd.depth == 1 || fd.depth == 2))
				|| (!use && fd.face == 3 && fd.depth != 0)
				|| (!use && fd.face == 1 && fd.depth != size - 1)
				|| (!use && (fd.face == 0 || fd.face == 2) && fd.depth != 1 && fd.depth != 2)))) {
			glPushMatrix();
			glTranslate(-s0 * FACET_LENGTH, 0, -s2 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, -1, f, -1, -1, -1, e);
			glPopMatrix();
		}
	}
	if (size > 4) { /* EDGE 2 */
		int s3, m1, m2;
		int s4 = size - 1;
		int a, b, c, d, e, f;
		s1 = 1;
		s2 = 2 * size - 5;
		s3 = 3;
		a = 5;
		b = 7;
		c = (size - 2) * (size - 2) + 1;
		d = s4 * s4 - 2;
		e = s4 * s4 + 3;
		f = size * size - 4;
		m1 = 1;
		m2 = 2;
		if (all || (use && (fd.face == 0 || fd.face == 1) && fd.depth == 0)
				|| (use && fd.face == 3 && fd.depth == m1)
				|| (use && fd.face == 2 && fd.depth == m2)
				|| (!use && (fd.face == 0 || fd.face == 1) && fd.depth != 0)
				|| (!use && fd.face == 3 && fd.depth != m1)
				|| (!use && fd.face == 2 && fd.depth != m2)) {
			glPushMatrix();
			glTranslate(s3 * FACET_LENGTH, s2 * FACET_LENGTH, -s1 * FACET_LENGTH);
			drawTetraFacet(w, a, -1, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && (fd.face == 0 || fd.face == 1) && fd.depth == 0)
				|| (use && fd.face == 2 && fd.depth == m1)
				|| (use && fd.face == 3 && fd.depth == m2)
				|| (!use && (fd.face == 0 || fd.face == 1) && fd.depth != 0)
				|| (!use && fd.face == 2 && fd.depth != m1)
				|| (!use && fd.face == 3 && fd.depth != m2)) {
			glPushMatrix();
			glTranslate(s3 * FACET_LENGTH, s2 * FACET_LENGTH, s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, b, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && (fd.face == 1 || fd.face == 2) && fd.depth == 0)
				|| (use && fd.face == 0 && fd.depth == m1)
				|| (use && fd.face == 3 && fd.depth == m2)
				|| (!use && (fd.face == 1 || fd.face == 2) && fd.depth != 0)
				|| (!use && fd.face == 0 && fd.depth != m1)
				|| (!use && fd.face == 3 && fd.depth != m2)) {
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, s2 * FACET_LENGTH, s3 * FACET_LENGTH);
			drawTetraFacet(w, -1, a, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && (fd.face == 1 || fd.face == 2) && fd.depth == 0)
				|| (use && fd.face == 3 && fd.depth == m1)
				|| (use && fd.face == 0 && fd.depth == m2)
				|| (!use && (fd.face == 1 || fd.face == 2) && fd.depth != 0)
				|| (!use && fd.face == 3 && fd.depth != m1)
				|| (!use && fd.face == 0 && fd.depth != m2)) {
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, s2 * FACET_LENGTH, s3 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, b, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && (fd.face == 2 || fd.face == 3) && fd.depth == 0)
				|| (use && fd.face == 1 && fd.depth == m1)
				|| (use && fd.face == 0 && fd.depth == m2)
				|| (!use && (fd.face == 2 || fd.face == 3) && fd.depth != 0)
				|| (!use && fd.face == 1 && fd.depth != m1)
				|| (!use && fd.face == 0 && fd.depth != m2)) {
			glPushMatrix();
			glTranslate(-s3 * FACET_LENGTH, s2 * FACET_LENGTH, s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, a, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && (fd.face == 2 || fd.face == 3) && fd.depth == 0)
				|| (use && fd.face == 0 && fd.depth == m1)
				|| (use && fd.face == 1 && fd.depth == m2)
				|| (!use && (fd.face == 2 || fd.face == 3) && fd.depth != 0)
				|| (!use && fd.face == 0 && fd.depth != m1)
				|| (!use && fd.face == 1 && fd.depth != m2)) {
			glPushMatrix();
			glTranslate(-s3 * FACET_LENGTH, s2 * FACET_LENGTH, -s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, b, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && (fd.face == 0 || fd.face == 3) && fd.depth == 0)
				|| (use && fd.face == 2 && fd.depth == m1)
				|| (use && fd.face == 1 && fd.depth == m2)
				|| (!use && (fd.face == 0 || fd.face == 3) && fd.depth != 0)
				|| (!use && fd.face == 2 && fd.depth != m1)
				|| (!use && fd.face == 1 && fd.depth != m2)) {
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, s2 * FACET_LENGTH, -s3 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, a, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && (fd.face == 0 || fd.face == 3) && fd.depth == 0)
				|| (use && fd.face == 1 && fd.depth == m1)
				|| (use && fd.face == 2 && fd.depth == m2)
				|| (!use && (fd.face == 0 || fd.face == 3) && fd.depth != 0)
				|| (!use && fd.face == 1 && fd.depth != m1)
				|| (!use && fd.face == 2 && fd.depth != m2)) {
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, s2 * FACET_LENGTH, -s3 * FACET_LENGTH);
			drawTetraFacet(w, b, -1, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}

		if (all || (use && (fd.face == 0 || fd.face == 3) && fd.depth == size - 1)
				|| (use && fd.face == 1 && fd.depth == size - 1 - m1)
				|| (use && fd.face == 2 && fd.depth == size - 1 - m2)
				|| (!use && (fd.face == 0 || fd.face == 3) && fd.depth != size - 1)
				|| (!use && fd.face == 1 && fd.depth != size - 1 - m1)
				|| (!use && fd.face == 2 && fd.depth != size - 1 - m2)) {
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, -s2 * FACET_LENGTH, s3 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, a, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && (fd.face == 0 || fd.face == 3) && fd.depth == size - 1)
				|| (use && fd.face == 2 && fd.depth == size - 1 - m1)
				|| (use && fd.face == 1 && fd.depth == size - 1 - m2)
				|| (!use && (fd.face == 0 || fd.face == 3) && fd.depth != size - 1)
				|| (!use && fd.face == 2 && fd.depth != size - 1 - m1)
				|| (!use && fd.face == 1 && fd.depth != size - 1 - m2)) {
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, -s2 * FACET_LENGTH, s3 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, b, -1, -1);
			glPopMatrix();
		}
		if (all || (use && (fd.face == 2 || fd.face == 3) && fd.depth == size - 1)
				|| (use && fd.face == 0 && fd.depth == size - 1 - m1)
				|| (use && fd.face == 1 && fd.depth == size - 1 - m2)
				|| (!use && (fd.face == 2 || fd.face == 3) && fd.depth != size - 1)
				|| (!use && fd.face == 0 && fd.depth != size - 1 - m1)
				|| (!use && fd.face == 1 && fd.depth != size - 1 - m2)) {
			glPushMatrix();
			glTranslate(s3 * FACET_LENGTH, -s2 * FACET_LENGTH, s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, a, -1, -1);
			glPopMatrix();
		}
		if (all || (use && (fd.face == 2 || fd.face == 3) && fd.depth == size - 1)
				|| (use && fd.face == 1 && fd.depth == size - 1 - m1)
				|| (use && fd.face == 0 && fd.depth == size - 1 - m2)
				|| (!use && (fd.face == 2 || fd.face == 3) && fd.depth != size - 1)
				|| (!use && fd.face == 1 && fd.depth != size - 1 - m1)
				|| (!use && fd.face == 0 && fd.depth != size - 1 - m2)) {
			glPushMatrix();
			glTranslate(s3 * FACET_LENGTH, -s2 * FACET_LENGTH, -s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, -1, b, -1);
			glPopMatrix();
		}
		if (all || (use && (fd.face == 1 || fd.face == 2) && fd.depth == size - 1)
				|| (use && fd.face == 3 && fd.depth == size - 1 - m1)
				|| (use && fd.face == 0 && fd.depth == size - 1 - m2)
				|| (!use && (fd.face == 1 || fd.face == 2) && fd.depth != size - 1)
				|| (!use && fd.face == 3 && fd.depth != size - 1 - m1)
				|| (!use && fd.face == 0 && fd.depth != size - 1 - m2)) {
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, -s2 * FACET_LENGTH, -s3 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, -1, a, -1);
			glPopMatrix();
		}
		if (all || (use && (fd.face == 1 || fd.face == 2) && fd.depth == size - 1)
				|| (use && fd.face == 0 && fd.depth == size - 1 - m1)
				|| (use && fd.face == 3 && fd.depth == size - 1 - m2)
				|| (!use && (fd.face == 1 || fd.face == 2) && fd.depth != size - 1)
				|| (!use && fd.face == 0 && fd.depth != size - 1 - m1)
				|| (!use && fd.face == 3 && fd.depth != size - 1 - m2)) {
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, -s2 * FACET_LENGTH, -s3 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, -1, -1, b);
			glPopMatrix();
		}
		if (all || (use && (fd.face == 0 || fd.face == 1) && fd.depth == size - 1)
				|| (use && fd.face == 2 && fd.depth == size - 1 - m1)
				|| (use && fd.face == 3 && fd.depth == size - 1 - m2)
				|| (!use && (fd.face == 0 || fd.face == 1) && fd.depth != size - 1)
				|| (!use && fd.face == 2 && fd.depth != size - 1 - m1)
				|| (!use && fd.face == 3 && fd.depth != size - 1 - m2)) {
			glPushMatrix();
			glTranslate(-s3 * FACET_LENGTH, -s2 * FACET_LENGTH, -s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, -1, -1, a);
			glPopMatrix();
		}
		if (all || (use && (fd.face == 0 || fd.face == 1) && fd.depth == size - 1)
				|| (use && fd.face == 3 && fd.depth == size - 1 - m1)
				|| (use && fd.face == 2 && fd.depth == size - 1 - m2)
				|| (!use && (fd.face == 0 || fd.face == 1) && fd.depth != size - 1)
				|| (!use && fd.face == 3 && fd.depth != size - 1 - m1)
				|| (!use && fd.face == 2 && fd.depth != size - 1 - m2)) {
			glPushMatrix();
			glTranslate(-s3 * FACET_LENGTH, -s2 * FACET_LENGTH, s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, b, -1, -1, -1);
			glPopMatrix();
		}

		if (all || (use && (fd.face == 0 || fd.face == 1) && fd.depth == 0)
				|| (use && fd.face == 2 && fd.depth == size - 1 - m1)
				|| (use && fd.face == 3 && fd.depth == size - 1 - m2)
				|| (!use && (fd.face == 0 || fd.face == 1) && fd.depth != 0)
				|| (!use && fd.face == 2 && fd.depth != size - 1 - m1)
				|| (!use && fd.face == 3 && fd.depth != size - 1 - m2)) {
			glPushMatrix();
			glTranslate(s2 * FACET_LENGTH, s3 * FACET_LENGTH, -s1 * FACET_LENGTH);
			drawTetraFacet(w, c, -1, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && (fd.face == 0 || fd.face == 1) && fd.depth == 0)
				|| (use && fd.face == 3 && fd.depth == size - 1 - m1)
				|| (use && fd.face == 2 && fd.depth == size - 1 - m2)
				|| (!use && (fd.face == 0 || fd.face == 1) && fd.depth != 0)
				|| (!use && fd.face == 3 && fd.depth != size - 1 - m1)
				|| (!use && fd.face == 2 && fd.depth != size - 1 - m2)) {
			glPushMatrix();
			glTranslate(s2 * FACET_LENGTH, s3 * FACET_LENGTH, s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, d, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && (fd.face == 1 || fd.face == 2) && fd.depth == 0)
				|| (use && fd.face == 3 && fd.depth == size - 1 - m1)
				|| (use && fd.face == 0 && fd.depth == size - 1 - m2)
				|| (!use && (fd.face == 1 || fd.face == 2) && fd.depth != 0)
				|| (!use && fd.face == 3 && fd.depth != size - 1 - m1)
				|| (!use && fd.face == 0 && fd.depth != size - 1 - m2)) {
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, s3 * FACET_LENGTH, s2 * FACET_LENGTH);
			drawTetraFacet(w, -1, c, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && (fd.face == 1 || fd.face == 2) && fd.depth == 0)
				|| (use && fd.face == 0 && fd.depth == size - 1 - m1)
				|| (use && fd.face == 3 && fd.depth == size - 1 - m2)
				|| (!use && (fd.face == 1 || fd.face == 2) && fd.depth != 0)
				|| (!use && fd.face == 0 && fd.depth != size - 1 - m1)
				|| (!use && fd.face == 3 && fd.depth != size - 1 - m2)) {
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, s3 * FACET_LENGTH, s2 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, d, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && (fd.face == 2 || fd.face == 3) && fd.depth == 0)
				|| (use && fd.face == 0 && fd.depth == size - 1 - m1)
				|| (use && fd.face == 1 && fd.depth == size - 1 - m2)
				|| (!use && (fd.face == 2 || fd.face == 3) && fd.depth != 0)
				|| (!use && fd.face == 0 && fd.depth != size - 1 - m1)
				|| (!use && fd.face == 1 && fd.depth != size - 1 - m2)) {
			glPushMatrix();
			glTranslate(-s2 * FACET_LENGTH, s3 * FACET_LENGTH, s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, c, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && (fd.face == 2 || fd.face == 3) && fd.depth == 0)
				|| (use && fd.face == 1 && fd.depth == size - 1 - m1)
				|| (use && fd.face == 0 && fd.depth == size - 1 - m2)
				|| (!use && (fd.face == 2 || fd.face == 3) && fd.depth != 0)
				|| (!use && fd.face == 1 && fd.depth != size - 1 - m1)
				|| (!use && fd.face == 0 && fd.depth != size - 1 - m2)) {
			glPushMatrix();
			glTranslate(-s2 * FACET_LENGTH, s3 * FACET_LENGTH, -s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, d, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && (fd.face == 0 || fd.face == 3) && fd.depth == 0)
				|| (use && fd.face == 1 && fd.depth == size - 1 - m1)
				|| (use && fd.face == 2 && fd.depth == size - 1 - m2)
				|| (!use && (fd.face == 0 || fd.face == 3) && fd.depth != 0)
				|| (!use && fd.face == 1 && fd.depth != size - 1 - m1)
				|| (!use && fd.face == 2 && fd.depth != size - 1 - m2)) {
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, s3 * FACET_LENGTH, -s2 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, c, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && (fd.face == 0 || fd.face == 3) && fd.depth == 0)
				|| (use && fd.face == 2 && fd.depth == size - 1 - m1)
				|| (use && fd.face == 1 && fd.depth == size - 1 - m2)
				|| (!use && (fd.face == 0 || fd.face == 3) && fd.depth != 0)
				|| (!use && fd.face == 2 && fd.depth != size - 1 - m1)
				|| (!use && fd.face == 1 && fd.depth != size - 1 - m2)) {
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, s3 * FACET_LENGTH, -s2 * FACET_LENGTH);
			drawTetraFacet(w, d, -1, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && (fd.face == 0 || fd.face == 3) && fd.depth == size - 1)
				|| (use && fd.face == 2 && fd.depth == m1)
				|| (use && fd.face == 1 && fd.depth == m2)
				|| (!use && (fd.face == 0 || fd.face == 3) && fd.depth != size - 1)
				|| (!use && fd.face == 2 && fd.depth != m1)
				|| (!use && fd.face == 1 && fd.depth != m2)) {
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, -s3 * FACET_LENGTH, s2 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, c, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && (fd.face == 0 || fd.face == 3) && fd.depth == size - 1)
				|| (use && fd.face == 1 && fd.depth == m1)
				|| (use && fd.face == 2 && fd.depth == m2)
				|| (!use && (fd.face == 0 || fd.face == 3) && fd.depth != size - 1)
				|| (!use && fd.face == 1 && fd.depth != m1)
				|| (!use && fd.face == 2 && fd.depth != m2)) {
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, -s3 * FACET_LENGTH, s2 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, d, -1, -1);
			glPopMatrix();
		}
		if (all || (use && (fd.face == 2 || fd.face == 3) && fd.depth == size - 1)
				|| (use && fd.face == 1 && fd.depth == m1)
				|| (use && fd.face == 0 && fd.depth == m2)
				|| (use && (fd.face == 0 || fd.face == 1) && fd.depth == m1)
				|| (!use && (fd.face == 2 || fd.face == 3) && fd.depth != size - 1)
				|| (!use && fd.face == 1 && fd.depth != m1)
				|| (!use && fd.face == 0 && fd.depth != m2)) {
			glPushMatrix();
			glTranslate(s2 * FACET_LENGTH, -s3 * FACET_LENGTH, s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, c, -1, -1);
			glPopMatrix();
		}
		if (all || (use && (fd.face == 2 || fd.face == 3) && fd.depth == size - 1)
				|| (use && fd.face == 0 && fd.depth == m1)
				|| (use && fd.face == 1 && fd.depth == m2)
				|| (!use && (fd.face == 2 || fd.face == 3) && fd.depth != size - 1)
				|| (!use && fd.face == 0 && fd.depth != m1)
				|| (!use && fd.face == 1 && fd.depth != m2)) {
			glPushMatrix();
			glTranslate(s2 * FACET_LENGTH, -s3 * FACET_LENGTH, -s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, -1, d, -1);
			glPopMatrix();
		}
		if (all || (use && (fd.face == 1 || fd.face == 2) && fd.depth == size - 1)
				|| (use && fd.face == 0 && fd.depth == m1)
				|| (use && fd.face == 3 && fd.depth == m2)
				|| (!use && (fd.face == 1 || fd.face == 2) && fd.depth != size - 1)
				|| (!use && fd.face == 0 && fd.depth != m1)
				|| (!use && fd.face == 3 && fd.depth != m2)) {
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, -s3 * FACET_LENGTH, -s2 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, -1, c, -1);
			glPopMatrix();
		}
		if (all || (use && (fd.face == 1 || fd.face == 2) && fd.depth == size - 1)
				|| (use && fd.face == 3 && fd.depth == m1)
				|| (use && fd.face == 0 && fd.depth == m2)
				|| (!use && (fd.face == 1 || fd.face == 2) && fd.depth != size - 1)
				|| (!use && fd.face == 3 && fd.depth != m1)
				|| (!use && fd.face == 0 && fd.depth != m2)) {
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, -s3 * FACET_LENGTH, -s2 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, -1, -1, d);
			glPopMatrix();
		}
		if (all || (use && (fd.face == 0 || fd.face == 1) && fd.depth == size - 1)
				|| (use && fd.face == 3 && fd.depth == m1)
				|| (use && fd.face == 2 && fd.depth == m2)
				|| (!use && (fd.face == 0 || fd.face == 1) && fd.depth != size - 1)
				|| (!use && fd.face == 3 && fd.depth != m1)
				|| (!use && fd.face == 2 && fd.depth != m2)) {
			glPushMatrix();
			glTranslate(-s2 * FACET_LENGTH, -s3 * FACET_LENGTH, -s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, -1, -1, c);
			glPopMatrix();
		}
		if (all || (use && (fd.face == 0 || fd.face == 1) && fd.depth == size - 1)
				|| (use && fd.face == 2 && fd.depth == m1)
				|| (use && fd.face == 3 && fd.depth == m2)
				|| (!use && (fd.face == 0 || fd.face == 1) && fd.depth != size - 1)
				|| (!use && fd.face == 2 && fd.depth != m1)
				|| (!use && fd.face == 3 && fd.depth != m2)) {
			glPushMatrix();
			glTranslate(-s2 * FACET_LENGTH, -s3 * FACET_LENGTH, s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, d, -1, -1, -1);
			glPopMatrix();
		}

		if (all || (use && fd.face == 0 && fd.depth == 0)
				|| (use && fd.face == 2 && fd.depth == size - 1)
				|| (use && fd.face == 1 && fd.depth == m1)
				|| (use && fd.face == 3 && fd.depth == size - 1 - m2)
				|| (!use && fd.face == 0 && fd.depth != 0)
				|| (!use && fd.face == 2 && fd.depth != size - 1)
				|| (!use && fd.face == 1 && fd.depth != m1)
				|| (!use && fd.face == 3 && fd.depth != size  - m2 - 1)) {
			glPushMatrix();
			glTranslate(s2 * FACET_LENGTH, s1 * FACET_LENGTH, -s3 * FACET_LENGTH);
			drawTetraFacet(w, e, -1, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && fd.face == 0 && fd.depth == 0)
				|| (use && fd.face == 2 && fd.depth == size - 1)
				|| (use && fd.face == 3 && fd.depth == size - 1 - m1)
				|| (use && fd.face == 1 && fd.depth == m2)
				|| (!use && fd.face == 0 && fd.depth != 0)
				|| (!use && fd.face == 2 && fd.depth != size - 1)
				|| (!use && fd.face == 3 && fd.depth != size - 1 - m1)
				|| (!use && fd.face == 1 && fd.depth != m2)) {
			glPushMatrix();
			glTranslate(s2 * FACET_LENGTH, -s1 * FACET_LENGTH, -s3 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, -1, f, -1);
			glPopMatrix();
		}
		if (all || (use && fd.face == 1 && fd.depth == 0)
				|| (use && fd.face == 3 && fd.depth == size - 1)
				|| (use && fd.face == 2 && fd.depth == m1)
				|| (use && fd.face == 0 && fd.depth == size - 1 - m2)
				|| (!use && fd.face == 1 && fd.depth != 0)
				|| (!use && fd.face == 3 && fd.depth != size - 1)
				|| (!use && fd.face == 2 && fd.depth != m1)
				|| (!use && fd.face == 0 && fd.depth != size - 1 - m2)) {
			glPushMatrix();
			glTranslate(s3 * FACET_LENGTH, s1 * FACET_LENGTH, s2 * FACET_LENGTH);
			drawTetraFacet(w, -1, e, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && fd.face == 1 && fd.depth == 0)
				|| (use && fd.face == 3 && fd.depth == size - 1)
				|| (use && fd.face == 0 && fd.depth == size - 1 - m1)
				|| (use && fd.face == 2 && fd.depth == m2)
				|| (!use && fd.face == 1 && fd.depth != 0)
				|| (!use && fd.face == 3 && fd.depth != size - 1)
				|| (!use && fd.face == 0 && fd.depth != size - 1 - m1)
				|| (!use && fd.face == 2 && fd.depth != m2)) {
			glPushMatrix();
			glTranslate(s3 * FACET_LENGTH, -s1 * FACET_LENGTH, s2 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, f, -1, -1);
			glPopMatrix();
		}
		if (all || (use && fd.face == 2 && fd.depth == 0)
				|| (use && fd.face == 0 && fd.depth == size - 1)
				|| (use && fd.face == 3 && fd.depth == m1)
				|| (use && fd.face == 1 && fd.depth == size - 1 - m2)
				|| (!use && fd.face == 2 && fd.depth != 0)
				|| (!use && fd.face == 0 && fd.depth != size - 1)
				|| (!use && fd.face == 3 && fd.depth != m1)
				|| (!use && fd.face == 1 && fd.depth != size - 1 - m2)) {
			glPushMatrix();
			glTranslate(-s2 * FACET_LENGTH, s1 * FACET_LENGTH, s3 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, e, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && fd.face == 2 && fd.depth == 0)
				|| (use && fd.face == 0 && fd.depth == size - 1)
				|| (use && fd.face == 1 && fd.depth == size - 1 - m1)
				|| (use && fd.face == 3 && fd.depth == m2)
				|| (!use && fd.face == 2 && fd.depth != 0)
				|| (!use && fd.face == 0 && fd.depth != size - 1)
				|| (!use && fd.face == 1 && fd.depth != size - 1 - m1)
				|| (!use && fd.face == 3 && fd.depth != m2)) {
			glPushMatrix();
			glTranslate(-s2 * FACET_LENGTH, -s1 * FACET_LENGTH, s3 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, f, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && fd.face == 3 && fd.depth == 0)
				|| (use && fd.face == 1 && fd.depth == size - 1)
				|| (use && fd.face == 0 && fd.depth == m1)
				|| (use && fd.face == 2 && fd.depth == size - 1 - m2)
				|| (!use && fd.face == 3 && fd.depth != 0)
				|| (!use && fd.face == 1 && fd.depth != size - 1)
				|| (!use && fd.face == 0 && fd.depth != m1)
				|| (!use && fd.face == 2 && fd.depth != size - 1 - m2)) {
			glPushMatrix();
			glTranslate(-s3 * FACET_LENGTH, s1 * FACET_LENGTH, -s2 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, e, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && fd.face == 3 && fd.depth == 0)
				|| (use && fd.face == 1 && fd.depth == size - 1)
				|| (use && fd.face == 2 && fd.depth == size - 1 - m1)
				|| (use && fd.face == 0 && fd.depth == m2)
				|| (!use && fd.face == 3 && fd.depth != 0)
				|| (!use && fd.face == 1 && fd.depth != size - 1)
				|| (!use && fd.face == 2 && fd.depth != size - 1 - m1)
				|| (!use && fd.face == 0 && fd.depth != m2)) {
			glPushMatrix();
			glTranslate(-s3 * FACET_LENGTH, -s1 * FACET_LENGTH, -s2 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, -1, -1, f);
			glPopMatrix();
		}
		if (all || (use && fd.face == 2 && fd.depth == 0)
				|| (use && fd.face == 0 && fd.depth == size - 1)
				|| (use && fd.face == 3 && fd.depth == size - 1 - m1)
				|| (use && fd.face == 1 && fd.depth == m2)
				|| (!use && fd.face == 2 && fd.depth != 0)
				|| (!use && fd.face == 0 && fd.depth != size - 1)
				|| (!use && fd.face == 3 && fd.depth != size - 1 - m1)
				|| (!use && fd.face == 1 && fd.depth != m2)) {
			glPushMatrix();
			glTranslate(-s3 * FACET_LENGTH, -s1 * FACET_LENGTH, s2 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, e, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && fd.face == 2 && fd.depth == 0)
				|| (use && fd.face == 0 && fd.depth == size - 1)
				|| (use && fd.face == 1 && fd.depth == m1)
				|| (use && fd.face == 3 && fd.depth == size - 1 - m2)
				|| (!use && fd.face == 2 && fd.depth != 0)
				|| (!use && fd.face == 0 && fd.depth != size - 1)
				|| (!use && fd.face == 1 && fd.depth != m1)
				|| (!use && fd.face == 3 && fd.depth != size - 1 - m2)) {
			glPushMatrix();
			glTranslate(-s3 * FACET_LENGTH, s1 * FACET_LENGTH, s2 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, f, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && fd.face == 1 && fd.depth == 0)
				|| (use && fd.face == 3 && fd.depth == size - 1)
				|| (use && fd.face == 2 && fd.depth == size - 1 - m1)
				|| (use && fd.face == 0 && fd.depth == m2)
				|| (!use && fd.face == 1 && fd.depth != 0)
				|| (!use && fd.face == 3 && fd.depth != size - 1)
				|| (!use && fd.face == 2 && fd.depth != size - 1 - m1)
				|| (!use && fd.face == 0 && fd.depth != m2)) {
			glPushMatrix();
			glTranslate(s2 * FACET_LENGTH, -s1 * FACET_LENGTH, s3 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, e, -1, -1);
			glPopMatrix();
		}
		if (all || (use && fd.face == 1 && fd.depth == 0)
				|| (use && fd.face == 3 && fd.depth == size - 1)
				|| (use && fd.face == 0 && fd.depth == m1)
				|| (use && fd.face == 2 && fd.depth == size - 1 - m2)
				|| (!use && fd.face == 1 && fd.depth != 0)
				|| (!use && fd.face == 3 && fd.depth != size - 1)
				|| (!use && fd.face == 0 && fd.depth != m1)
				|| (!use && fd.face == 2 && fd.depth != size - 1 - m2)) {
			glPushMatrix();
			glTranslate(s2 * FACET_LENGTH, s1 * FACET_LENGTH, s3 * FACET_LENGTH);
			drawTetraFacet(w, -1, f, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && fd.face == 0 && fd.depth == 0)
				|| (use && fd.face == 2 && fd.depth == size - 1)
				|| (use && fd.face == 1 && fd.depth == size - 1 - m1)
				|| (use && fd.face == 3 && fd.depth == m2)
				|| (!use && fd.face == 0 && fd.depth != 0)
				|| (!use && fd.face == 2 && fd.depth != size - 1)
				|| (!use && fd.face == 1 && fd.depth != size - 1 - m1)
				|| (!use && fd.face == 3 && fd.depth != m2)) {
			glPushMatrix();
			glTranslate(s3 * FACET_LENGTH, -s1 * FACET_LENGTH, -s2 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, -1, e, -1);
			glPopMatrix();
		}
		if (all || (use && fd.face == 0 && fd.depth == 0)
				|| (use && fd.face == 2 && fd.depth == size - 1)
				|| (use && fd.face == 3 && fd.depth == m1)
				|| (use && fd.face == 1 && fd.depth == size - 1 - m2)
				|| (!use && fd.face == 0 && fd.depth != 0)
				|| (!use && fd.face == 2 && fd.depth != size - 1)
				|| (!use && fd.face == 3 && fd.depth != m1)
				|| (!use && fd.face == 1 && fd.depth != size - 1 - m2)) {
			glPushMatrix();
			glTranslate(s3 * FACET_LENGTH, s1 * FACET_LENGTH, -s2 * FACET_LENGTH);
			drawTetraFacet(w, f, -1, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && fd.face == 3 && fd.depth == 0)
				|| (use && fd.face == 1 && fd.depth == size - 1)
				|| (use && fd.face == 0 && fd.depth == size - 1 - m1)
				|| (use && fd.face == 2 && fd.depth == m2)
				|| (!use && fd.face == 3 && fd.depth != 0)
				|| (!use && fd.face == 1 && fd.depth != size - 1)
				|| (!use && fd.face == 0 && fd.depth != size - 1 - m1)
				|| (!use && fd.face == 2 && fd.depth != m2)) {
			glPushMatrix();
			glTranslate(-s2 * FACET_LENGTH, -s1 * FACET_LENGTH, -s3 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, -1, -1, e);
			glPopMatrix();
		}
		if (all || (use && fd.face == 3 && fd.depth == 0)
				|| (use && fd.face == 1 && fd.depth == size - 1)
				|| (use && fd.face == 2 && fd.depth == m1)
				|| (use && fd.face == 0 && fd.depth == size - 1 - m2)
				|| (!use && fd.face == 3 && fd.depth != 0)
				|| (!use && fd.face == 1 && fd.depth != size - 1)
				|| (!use && fd.face == 2 && fd.depth != m1)
				|| (!use && fd.face == 0 && fd.depth != size - 1 - m2)) {
			glPushMatrix();
			glTranslate(-s2 * FACET_LENGTH, s1 * FACET_LENGTH, -s3 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, f, -1, -1, -1, -1);
			glPopMatrix();
		}
		/* FACE 2 */
		s1 = 2;
		s2 = 2 * size - 6;
		s3 = size - 2;
		a = 6;
		b = s3 * s3 + 2; /* 11, 18, 27 */
		c = s3 * s3 + 2 * s3 - 2; /* 13, 22, 33 */
		m1 = 1;
		m2 = 2;
		if (all || (use && fd.face == 0 && fd.depth == 0)
				|| (use && (fd.face == 1 || fd.face == 3) && fd.depth == m1)
				|| (use && fd.face == 2 && fd.depth == m2)
				|| (!use && fd.face == 0 && fd.depth != 0)
				|| (!use && (fd.face == 1 || fd.face == 3) && fd.depth != m1)
				|| (!use && fd.face == 2 && fd.depth != m2)) {
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, s2 * FACET_LENGTH, -s1 * FACET_LENGTH);
			drawOctaFacet(w, a, -1, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && fd.face == 0 && fd.depth == 0)
				|| (use && fd.face == 1 && fd.depth == m1)
				|| (use && fd.face == 2 && fd.depth == size - 1 - m1)
				|| (use && fd.face == 3 && fd.depth == size - 1 - m2)
				|| (!use && fd.face == 0 && fd.depth != 0)
				|| (!use && fd.face == 1 && fd.depth != m1)
				|| (!use && fd.face == 2 && fd.depth != size - 1 - m1)
				|| (!use && fd.face == 3 && fd.depth != size - 1 - m2)) {
			glPushMatrix();
			glTranslate(s2 * FACET_LENGTH, s1 * FACET_LENGTH, -s1 * FACET_LENGTH);
			drawOctaFacet(w, b, -1, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && fd.face == 0 && fd.depth == 0)
				|| (use && fd.face == 3 && fd.depth == m1)
				|| (use && fd.face == 2 && fd.depth == size - 1 - m1)
				|| (use && fd.face == 1 && fd.depth == size - 1 - m2)
				|| (!use && fd.face == 0 && fd.depth != 0)
				|| (!use && fd.face == 3 && fd.depth != m1)
				|| (!use && fd.face == 2 && fd.depth != size - 1 - m1)
				|| (!use && fd.face == 1 && fd.depth != size - 1 - m2)) {
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, s1 * FACET_LENGTH, -s2 * FACET_LENGTH);
			drawOctaFacet(w, c, -1, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && fd.face == 1 && fd.depth == 0)
				|| (use && (fd.face == 0 || fd.face == 2) && fd.depth == m1)
				|| (use && fd.face == 3 && fd.depth == m2)
				|| (!use && fd.face == 1 && fd.depth != 0)
				|| (!use && (fd.face == 0 || fd.face == 2) && fd.depth != m1)
				|| (!use && fd.face == 3 && fd.depth != m2)) {
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, s2 * FACET_LENGTH, s1 * FACET_LENGTH);
			drawOctaFacet(w, -1, a, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && fd.face == 1 && fd.depth == 0)
				|| (use && fd.face == 2  && fd.depth == m1)
				|| (use && fd.face == 3 && fd.depth == size - 1 - m1)
				|| (use && fd.face == 0 && fd.depth == size - 1 - m2)
				|| (!use && fd.face == 1 && fd.depth != 0)
				|| (!use && fd.face == 2 && fd.depth != m1)
				|| (!use && fd.face == 3 && fd.depth != size - 1 - m1)
				|| (!use && fd.face == 0 && fd.depth != size - 1 - m2)) {
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, s1 * FACET_LENGTH, s2 * FACET_LENGTH);
			drawOctaFacet(w, -1, b, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && fd.face == 1 && fd.depth == 0)
				|| (use && fd.face == 0 && fd.depth == m1)
				|| (use && fd.face == 3 && fd.depth == size - 1 - m1)
				|| (use && fd.face == 2 && fd.depth == size - 1 - m2)
				|| (!use && fd.face == 1 && fd.depth != 0)
				|| (!use && fd.face == 0 && fd.depth != m1)
				|| (!use && fd.face == 3 && fd.depth != size - 1 - m1)
				|| (!use && fd.face == 2 && fd.depth != size - 1 - m2)) {
			glPushMatrix();
			glTranslate(s2 * FACET_LENGTH, s1 * FACET_LENGTH, s1 * FACET_LENGTH);
			drawOctaFacet(w, -1, c, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && fd.face == 2 && fd.depth == 0)
				|| (use && (fd.face == 1 || fd.face == 3) && fd.depth == m1)
				|| (use && fd.face == 0 && fd.depth == m2)
				|| (!use && fd.face == 2 && fd.depth != 0)
				|| (!use && (fd.face == 1 || fd.face == 3) && fd.depth != m1)
				|| (!use && fd.face == 0 && fd.depth != m2)) {
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, s2 * FACET_LENGTH, s1 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, a, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && fd.face == 2 && fd.depth == 0)
				|| (use && fd.face == 3 && fd.depth == m1)
				|| (use && fd.face == 0 && fd.depth == size - 1 - m1)
				|| (use && fd.face == 1 && fd.depth == size - 1 - m2)
				|| (!use && fd.face == 2 && fd.depth != 0)
				|| (!use && fd.face == 3 && fd.depth != m1)
				|| (!use && fd.face == 0 && fd.depth != size - 1 - m1)
				|| (!use && fd.face == 1 && fd.depth != size - 1 - m2)) {
			glPushMatrix();
			glTranslate(-s2 * FACET_LENGTH, s1 * FACET_LENGTH, s1 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, b, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && fd.face == 2 && fd.depth == 0)
				|| (use && fd.face == 1 && fd.depth == m1)
				|| (use && fd.face == 0 && fd.depth == size - 1 - m1)
				|| (use && fd.face == 3 && fd.depth == size - 1 - m2)
				|| (!use && fd.face == 2 && fd.depth != 0)
				|| (!use && fd.face == 1 && fd.depth != m1)
				|| (!use && fd.face == 0 && fd.depth != size - 1 - m1)
				|| (!use && fd.face == 3 && fd.depth != size - 1 - m2)) {
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, s1 * FACET_LENGTH, s2 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, c, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && fd.face == 3 && fd.depth == 0)
				|| (use && (fd.face == 0 || fd.face == 2) && fd.depth == m1)
				|| (use && fd.face == 1 && fd.depth == m2)
				|| (!use && fd.face == 3 && fd.depth != 0)
				|| (!use && (fd.face == 0 || fd.face == 2) && fd.depth != m1)
				|| (!use && fd.face == 1 && fd.depth != m2)) {
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, s2 * FACET_LENGTH, -s1 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, -1, a, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && fd.face == 3 && fd.depth == 0)
				|| (use && fd.face == 0  && fd.depth == m1)
				|| (use && fd.face == 1 && fd.depth == size - 1 - m1)
				|| (use && fd.face == 2 && fd.depth == size - 1 - m2)
				|| (!use && fd.face == 3 && fd.depth != 0)
				|| (!use && fd.face == 0 && fd.depth != m1)
				|| (!use && fd.face == 1 && fd.depth != size - 1 - m1)
				|| (!use && fd.face == 2 && fd.depth != size - 1 - m2)) {
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, s1 * FACET_LENGTH, -s2 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, -1, b, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && fd.face == 3 && fd.depth == 0)
				|| (use && fd.face == 2 && fd.depth == m1)
				|| (use && fd.face == 1 && fd.depth == size - 1 - m1)
				|| (use && fd.face == 0 && fd.depth == size - 1 - m2)
				|| (!use && fd.face == 3 && fd.depth != 0)
				|| (!use && fd.face == 2 && fd.depth != m1)
				|| (!use && fd.face == 1 && fd.depth != size - 1 - m1)
				|| (!use && fd.face == 0 && fd.depth != size - 1 - m2)) {
			glPushMatrix();
			glTranslate(-s2 * FACET_LENGTH, s1 * FACET_LENGTH, -s1 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, -1, c, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && fd.face == 0 && fd.depth == size - 1)
				|| (use && (fd.face == 1 || fd.face == 3) && fd.depth == size - 1 - m1)
				|| (use && fd.face == 2 && fd.depth == size - 1 - m2)
				|| (!use && fd.face == 0 && fd.depth != size - 1)
				|| (!use && (fd.face == 1 || fd.face == 3) && fd.depth != size - 1 - m1)
				|| (!use && fd.face == 2 && fd.depth != size - 1 - m2)) {
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, -s2 * FACET_LENGTH, s1 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, -1, -1, a, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && fd.face == 0 && fd.depth == size - 1)
				|| (use && fd.face == 3 && fd.depth == size - 1 - m1)
				|| (use && fd.face == 2 && fd.depth == m1)
				|| (use && fd.face == 1 && fd.depth == m2)
				|| (!use && fd.face == 0 && fd.depth != size - 1)
				|| (!use && fd.face == 3 && fd.depth != size - 1 - m1)
				|| (!use && fd.face == 2 && fd.depth != m1)
				|| (!use && fd.face == 1 && fd.depth != m2)) {
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, -s1 * FACET_LENGTH, s2 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, -1, -1, b, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && fd.face == 0 && fd.depth == size - 1)
				|| (use && fd.face == 1 && fd.depth == size - 1 - m1)
				|| (use && fd.face == 2 && fd.depth == m1)
				|| (use && fd.face == 3 && fd.depth == m2)
				|| (!use && fd.face == 0 && fd.depth != size - 1)
				|| (!use && fd.face == 1 && fd.depth != size - 1 - m1)
				|| (!use && fd.face == 2 && fd.depth != m1)
				|| (!use && fd.face == 3 && fd.depth != m2)) {
			glPushMatrix();
			glTranslate(-s2 * FACET_LENGTH, -s1 * FACET_LENGTH, s1 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, -1, -1, c, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && fd.face == 3 && fd.depth == size - 1)
				|| (use && (fd.face == 0 || fd.face == 2) && fd.depth == size - 1 - m1)
				|| (use && fd.face == 1 && fd.depth == size - 1 - m2)
				|| (!use && fd.face == 3 && fd.depth != size - 1)
				|| (!use && (fd.face == 0 || fd.face == 2) && fd.depth != size - 1 - m1)
				|| (!use && fd.face == 1 && fd.depth != size - 1 - m2)) {
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, -s2 * FACET_LENGTH, s1 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, -1, -1, -1, a, -1, -1);
			glPopMatrix();
		}
		if (all || (use && fd.face == 3 && fd.depth == size - 1)
				|| (use && fd.face == 2 && fd.depth == size - 1 - m1)
				|| (use && fd.face == 1 && fd.depth == m1)
				|| (use && fd.face == 0 && fd.depth == m2)
				|| (!use && fd.face == 3 && fd.depth != size - 1)
				|| (!use && fd.face == 2 && fd.depth != size - 1 - m1)
				|| (!use && fd.face == 1 && fd.depth != m1)
				|| (!use && fd.face == 0 && fd.depth != m2)) {
			glPushMatrix();
			glTranslate(s2 * FACET_LENGTH, -s1 * FACET_LENGTH, s1 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, -1, -1, -1, b, -1, -1);
			glPopMatrix();
		}
		if (all || (use && fd.face == 3 && fd.depth == size - 1)
				|| (use && fd.face == 0 && fd.depth == size - 1 - m1)
				|| (use && fd.face == 1 && fd.depth == m1)
				|| (use && fd.face == 2 && fd.depth == m2)
				|| (!use && fd.face == 3 && fd.depth != size - 1)
				|| (!use && fd.face == 0 && fd.depth != size - 1 - m1)
				|| (!use && fd.face == 1 && fd.depth != m1)
				|| (!use && fd.face == 2 && fd.depth != m2)) {
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, -s1 * FACET_LENGTH, s2 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, -1, -1, -1, c, -1, -1);
			glPopMatrix();
		}
		if (all || (use && fd.face == 2 && fd.depth == size - 1)
				|| (use && (fd.face == 1 || fd.face == 3) && fd.depth == size - 1 - m1)
				|| (use && fd.face == 0 && fd.depth == size - 1 - m2)
				|| (!use && fd.face == 2 && fd.depth != size - 1)
				|| (!use && (fd.face == 1 || fd.face == 3) && fd.depth != size - 1 - m1)
				|| (!use && fd.face == 0 && fd.depth != size - 1 - m2)) {
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, -s2 * FACET_LENGTH, -s1 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, -1, -1, -1, -1, a, -1);
			glPopMatrix();
		}
		if (all || (use && fd.face == 2 && fd.depth == size - 1)
				|| (use && fd.face == 1 && fd.depth == size - 1 - m1)
				|| (use && fd.face == 0 && fd.depth == m1)
				|| (use && fd.face == 3 && fd.depth == m2)
				|| (!use && fd.face == 2 && fd.depth != size - 1)
				|| (!use && fd.face == 1 && fd.depth != size - 1 - m1)
				|| (!use && fd.face == 0 && fd.depth != m1)
				|| (!use && fd.face == 3 && fd.depth != m2)) {
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, -s1 * FACET_LENGTH, -s2 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, -1, -1, -1, -1, b, -1);
			glPopMatrix();
		}
		if (all || (use && fd.face == 2 && fd.depth == size - 1)
				|| (use && fd.face == 3 && fd.depth == size - 1 - m1)
				|| (use && fd.face == 0 && fd.depth == m1)
				|| (use && fd.face == 1 && fd.depth == m2)
				|| (!use && fd.face == 2 && fd.depth != size - 1)
				|| (!use && fd.face == 3 && fd.depth != size - 1 - m1)
				|| (!use && fd.face == 0 && fd.depth != m1)
				|| (!use && fd.face == 1 && fd.depth != m2)) {
			glPushMatrix();
			glTranslate(s2 * FACET_LENGTH, -s1 * FACET_LENGTH, -s1 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, -1, -1, -1, -1, c, -1);
			glPopMatrix();
		}
		if (all || (use && fd.face == 1 && fd.depth == size - 1)
				|| (use && (fd.face == 0 || fd.face == 2) && fd.depth == size - 1 - m1)
				|| (use && fd.face == 3 && fd.depth == size - 1 - m2)
				|| (!use && fd.face == 1 && fd.depth != size - 1)
				|| (!use && (fd.face == 0 || fd.face == 2) && fd.depth != size - 1 - m1)
				|| (!use && fd.face == 3 && fd.depth != size - 1 - m2)) {
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, -s2 * FACET_LENGTH, -s1 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, -1, -1, -1, -1, -1, a);
			glPopMatrix();
		}
		if (all || (use && fd.face == 1 && fd.depth == size - 1)
				|| (use && fd.face == 0  && fd.depth == size - 1 - m1)
				|| (use && fd.face == 3 && fd.depth == m1)
				|| (use && fd.face == 2 && fd.depth == m2)
				|| (!use && fd.face == 1 && fd.depth != size - 1)
				|| (!use && fd.face == 0 && fd.depth != size - 1 - m1)
				|| (!use && fd.face == 3 && fd.depth != m1)
				|| (!use && fd.face == 2 && fd.depth != m2)) {
			glPushMatrix();
			glTranslate(-s2 * FACET_LENGTH, -s1 * FACET_LENGTH, -s1 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, -1, -1, -1, -1, -1, b);
			glPopMatrix();
		}
		if (all || (use && fd.face == 1 && fd.depth == size - 1)
				|| (use && fd.face == 2 && fd.depth == size - 1 - m1)
				|| (use && fd.face == 3 && fd.depth == m1)
				|| (use && fd.face == 0 && fd.depth == m2)
				|| (!use && fd.face == 1 && fd.depth != size - 1)
				|| (!use && fd.face == 2 && fd.depth != size - 1 - m1)
				|| (!use && fd.face == 3 && fd.depth != m1)
				|| (!use && fd.face == 0 && fd.depth != m2)) {
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, -s1 * FACET_LENGTH, -s2 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, -1, -1, -1, -1, -1, c);
			glPopMatrix();
		}
	}
}

typedef struct _CornerDepth {
	int corner, depth;
} CornerDepth;

static void
cornerDepth(OctWidget w, int face, int position, int direction, CornerDepth *cd)
{
	RTT rtt;

	toRTT(position, &rtt);
	switch (face) {
	case 0:
		if (direction == BR || direction == TL) {
			cd->corner = 0;
			cd->depth = w->oct.size - 1 - rtt.tlbr;
		} else if (direction == TR || direction == BL) {
			cd->corner = 1;
			cd->depth = w->oct.size - 1 + rtt.trbl;
		} else {
			cd->corner = 2;
			cd->depth = rtt.row;
		}
		break;
	case 1:
		if (direction == BR || direction == TL) {
			cd->corner = 0;
			cd->depth = w->oct.size - 1 - rtt.trbl;
		} else if (direction == TR || direction == BL) {
			cd->corner = 1;
			cd->depth = w->oct.size - 1 - rtt.tlbr;
		} else {
			cd->corner = 2;
			cd->depth = rtt.row;
		}
		break;
	case 2:
		if (direction == BR || direction == TL) {
			cd->corner = 0;
			cd->depth = w->oct.size - 1 + rtt.tlbr;
		} else if (direction == TR || direction == BL) {
			cd->corner = 1;
			cd->depth = w->oct.size - 1 - rtt.trbl;
		} else {
			cd->corner = 2;
			cd->depth = rtt.row;
		}
		break;
	case 3:
		if (direction == BR || direction == TL) {
			cd->corner = 0;
			cd->depth = w->oct.size - 1 + rtt.trbl;
		} else if (direction == TR || direction == BL) {
			cd->corner = 1;
			cd->depth = w->oct.size - 1 + rtt.tlbr;
		} else {
			cd->corner = 2;
			cd->depth = rtt.row;
		}
		break;
	case 4:
		if (direction == TR || direction == BL) {
			cd->corner = 0;
			cd->depth = w->oct.size - 1 + rtt.trbl;
		} else if (direction == BR || direction == TL) {
			cd->corner = 1;
			cd->depth = w->oct.size - 1 - rtt.tlbr;
		} else {
			cd->corner = 2;
			cd->depth = 2 * (w->oct.size - 1) - rtt.row;
		}
		break;
	case 5:
		if (direction == TR || direction == BL) {
			cd->corner = 0;
			cd->depth = w->oct.size - 1 - rtt.tlbr;
		} else if (direction == BR || direction == TL) {
			cd->corner = 1;
			cd->depth = w->oct.size - 1 - rtt.trbl;
		} else {
			cd->corner = 2;
			cd->depth = 2 * (w->oct.size - 1) - rtt.row;
		}
		break;
	case 6:
		if (direction == TR || direction == BL) {
			cd->corner = 0;
			cd->depth = w->oct.size - 1 - rtt.trbl;
		} else if (direction == BR || direction == TL) {
			cd->corner = 1;
			cd->depth = w->oct.size - 1 + rtt.tlbr;
		} else {
			cd->corner = 2;
			cd->depth = 2 * (w->oct.size - 1) - rtt.row;
		}
		break;
	case 7:
		if (direction == TR || direction == BL) {
			cd->corner = 0;
			cd->depth = w->oct.size - 1 + rtt.tlbr;
		} else if (direction == BR || direction == TL) {
			cd->corner = 1;
			cd->depth = w->oct.size - 1 + rtt.trbl;
		} else {
			cd->corner = 2;
			cd->depth = 2 * (w->oct.size - 1) - rtt.row;
		}
		break;
	default:
		if (face != -1) {
			(void) printf("cornerDepth error: face %d, position %d, direction %d\n",
				face, position, direction);
		}
		cd->corner = 0;
		cd->depth = 0;
	}
}

/* Almost unnoticable drawing error as the octahedrons turn through the face
   of the puzzle (it looks like a small shadow).  Octahedrons should be cut
   up to pyramids and half pyramids to fix this. TODO */
static void
drawCorners(OctGLWidget w, int face, int position, int direction,
		Boolean use, Boolean all)
{
	int s0, s1, s2, i, j, k;
	int size = w->oct.size;
	Boolean tetra, sticky = w->oct.sticky;
	RTT rtt;
	CornerDepth cd;

	toRTT(position, &rtt);
	cornerDepth((OctWidget) w, face, position, direction, &cd);
#ifdef DEBUG
	(void) printf("drawCorners: corner %d, depth %d\n", cd.corner, cd.depth);
#endif
	if (size == 1 && (all || use))
		drawOctaFacet(w, 0, 0, 0, 0, 0, 0, 0, 0);
	if (size > 1) { /* CORNERS */
		s2 = 2 * size - 2;
		j = (size - 1) * (size - 1);
		k = size * size - 1;
		if (all || (!sticky && ((use && cd.corner == 0 && cd.depth == 0)
				|| (use && cd.corner != 0 && cd.depth == size - 1)
				|| (!use && cd.corner == 0 && cd.depth != 0)
				|| (!use && cd.corner != 0 && cd.depth != size - 1)))
			|| (sticky && ((use && cd.corner == 0 && cd.depth < size - 1)
				|| (use && cd.corner != 0 && cd.depth == size - 1)
				|| (!use && cd.corner == 0 && cd.depth >= size - 1)
				|| (!use && cd.corner != 0 && cd.depth != size - 1)))) {
			glPushMatrix();
			glTranslate(s2 * FACET_LENGTH, 0, 0);
			drawOctaFacet(w, j, k, -1, -1, -1, j, k, -1); /* TR */
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 1 && cd.depth == 0)
				|| (use && cd.corner != 1 && cd.depth == size - 1)
				|| (!use && cd.corner == 1 && cd.depth != 0)
				|| (!use && cd.corner != 1 && cd.depth != size - 1)))
			|| (sticky && ((use && cd.corner == 1 && cd.depth < size - 1)
				|| (use && cd.corner != 1 && cd.depth == size - 1)
				|| (!use && cd.corner == 1 && cd.depth >= size - 1)
				|| (!use && cd.corner != 1 && cd.depth != size - 1)))) {
			glPushMatrix();
			glTranslate(0, 0, s2 * FACET_LENGTH);
			drawOctaFacet(w, -1, j, k, -1, j, k, -1, -1); /* BR */
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 0 && cd.depth == 2 * size - 2) 
				|| (use && cd.corner != 0 && cd.depth == size - 1)
				|| (!use && cd.corner == 0 && cd.depth != 2 * size - 2)
				|| (!use && cd.corner != 0 && cd.depth != size - 1)))
			|| (sticky && ((use && cd.corner == 0 && cd.depth > size - 1)
				|| (use && cd.corner != 0 && cd.depth == size - 1)
				|| (!use && cd.corner == 0 && cd.depth <= size - 1)
				|| (!use && cd.corner != 0 && cd.depth != size - 1)))) {
			glPushMatrix();
			glTranslate(-s2 * FACET_LENGTH, 0, 0);
			drawOctaFacet(w, -1, -1, j, k, k, -1, -1, j); /* BL */
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 1 && cd.depth == 2 * size - 2)
				|| (use && cd.corner != 1 && cd.depth == size - 1)
				|| (!use && cd.corner == 1 && cd.depth != 2 * size - 2)
				|| (!use && cd.corner != 1 && cd.depth != size - 1)))
			|| (sticky && ((use && cd.corner == 1 && cd.depth > size - 1)
				|| (use && cd.corner != 1 && cd.depth == size - 1)
				|| (!use && cd.corner == 1 && cd.depth <= size - 1)
				|| (!use && cd.corner != 1 && cd.depth != size - 1)))) {
			glPushMatrix();
			glTranslate(0, 0, -s2 * FACET_LENGTH);
			drawOctaFacet(w, k, -1, -1, j, -1, -1, j, k); /* TL */
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 2 && cd.depth == 0)
				|| (use && cd.corner != 2 && cd.depth == size - 1)
				|| (!use && cd.corner == 2 && cd.depth != 0)
				|| (!use && cd.corner != 2 && cd.depth != size - 1)))
			|| (sticky && ((use && cd.corner == 2 && cd.depth < size - 1)
				|| (use && cd.corner != 2 && cd.depth == size - 1)
				|| (!use && cd.corner == 2 && cd.depth >= size - 1)
				|| (!use && cd.corner != 2 && cd.depth != size - 1)))) {
			glPushMatrix();
			glTranslate(0, s2 * FACET_LENGTH, 0);
			drawOctaFacet(w, 0, 0, 0, 0, -1, -1, -1, -1); /* TOP */
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 2 && cd.depth == 2 * size - 2)
				|| (use && cd.corner != 2 && cd.depth == size - 1)
				|| (!use && cd.corner == 2 && cd.depth != 2 * size - 2)
				|| (!use && cd.corner != 2 && cd.depth != size - 1)))
			|| (sticky && ((use && cd.corner == 2 && cd.depth > size - 1)
				|| (use && cd.corner != 2 && cd.depth == size - 1)
				|| (!use && cd.corner == 2 && cd.depth <= size - 1)
				|| (!use && cd.corner != 2 && cd.depth != size - 1)))) {
			glPushMatrix();
			glTranslate(0, -s2 * FACET_LENGTH, 0);
			drawOctaFacet(w, -1, -1, -1, -1, 0, 0, 0, 0); /* BOTTOM */
			glPopMatrix();
		}
	}
	if (size > 1 && size % 3 != 0) { /* CENTERS */
		tetra = (size % 3 == 2); /* 2, 6, 12, 20, 30 */
		if (tetra) {
			s2 = ((size - 2) / 3) * 2 + 1;
		} else {
			s2 = ((size - 1) / 3) * 2;
		}
		k = s2 * s2 + s2;
		i = s2;
		s1 = size - 1 - s2;
		if (all || (!sticky && ((use && cd.corner != 1 && cd.depth == size - 1 - s1)
				|| (use && cd.corner == 1 && cd.depth == size - 1 + s1)
				|| (!use && cd.corner != 1 && cd.depth != size - 1 - s1)
				|| (!use && cd.corner == 1 && cd.depth != size - 1 + s1)))
			|| (sticky && ((use && cd.corner != 1 && cd.depth < size - 1)
				|| (use && cd.corner == 1 && cd.depth > size - 1)
				|| (!use && cd.corner != 1 && cd.depth >= size - 1)
				|| (!use && cd.corner == 1 && cd.depth <= size - 1)))) {
			glPushMatrix();
			glTranslate(i * FACET_LENGTH, i * FACET_LENGTH, -i * FACET_LENGTH);
			drawFacet(w, k, -1, -1, -1, -1, -1, -1, -1, tetra); /* 0 */
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.depth == size - 1 - s1)
				|| (!use && cd.depth != size - 1 - s1)))
			|| (sticky && ((use && cd.depth < size - 1)
				|| (!use && cd.depth >= size - 1)))) {
			glPushMatrix();
			glTranslate(i * FACET_LENGTH, i * FACET_LENGTH, i * FACET_LENGTH);
			drawFacet(w, -1, k, -1, -1, -1, -1, -1, -1, tetra); /* 1 */
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner != 0 && cd.depth == size - 1 - s1)
				|| (use && cd.corner == 0 && cd.depth == size - 1 + s1)
				|| (!use && cd.corner != 0 && cd.depth != size - 1 - s1)
				|| (!use && cd.corner == 0 && cd.depth != size - 1 + s1)))
			|| (sticky && ((use && cd.corner != 0 && cd.depth < size - 1)
				|| (use && cd.corner == 0 && cd.depth > size - 1)
				|| (!use && cd.corner != 0 && cd.depth >= size - 1)
				|| (!use && cd.corner == 0 && cd.depth <= size - 1)))) {
			glPushMatrix();
			glTranslate(-i * FACET_LENGTH, i * FACET_LENGTH, i * FACET_LENGTH);
			drawFacet(w, -1, -1, k, -1, -1, -1, -1, -1, tetra); /* 2 */
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner != 2 && cd.depth == size - 1 + s1)
				|| (use && cd.corner == 2 && cd.depth == size - 1 - s1)
				|| (!use && cd.corner != 2 && cd.depth != size - 1 + s1)
				|| (!use && cd.corner == 2 && cd.depth != size - 1 - s1)))
			|| (sticky && ((use && cd.corner != 2 && cd.depth > size - 1)
				|| (use && cd.corner == 2 && cd.depth < size - 1)
				|| (!use && cd.corner != 2 && cd.depth <= size - 1)
				|| (!use && cd.corner == 2 && cd.depth >= size - 1)))) {
			glPushMatrix();
			glTranslate(-i * FACET_LENGTH, i * FACET_LENGTH, -i * FACET_LENGTH);
			drawFacet(w, -1, -1, -1, k, -1, -1, -1, -1, tetra); /* 3 */
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner != 1 && cd.depth == size - 1 + s1)
				|| (use && cd.corner == 1 && cd.depth == size - 1 - s1)
				|| (!use && cd.corner != 1 && cd.depth != size - 1 + s1)
				|| (!use && cd.corner == 1 && cd.depth != size - 1 - s1)))
			|| (sticky && ((use && cd.corner != 1 && cd.depth > size - 1)
				|| (use && cd.corner == 1 && cd.depth < size - 1)
				|| (!use && cd.corner != 1 && cd.depth <= size - 1)
				|| (!use && cd.corner == 1 && cd.depth >= size - 1)))) {
			glPushMatrix();
			glTranslate(-i * FACET_LENGTH, -i * FACET_LENGTH, i * FACET_LENGTH);
			drawFacet(w, -1, -1, -1, -1, k, -1, -1, -1, tetra); /* 4 */
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner != 2 && cd.depth == size - 1 - s1)
				|| (use && cd.corner == 2 && cd.depth == size - 1 + s1)
				|| (!use && cd.corner != 2 && cd.depth != size - 1 - s1)
				|| (!use && cd.corner == 2 && cd.depth != size - 1 + s1)))
			|| (sticky && ((use && cd.corner != 2 && cd.depth < size - 1)
				|| (use && cd.corner == 2 && cd.depth > size - 1)
				|| (!use && cd.corner != 2 && cd.depth >= size - 1)
				|| (!use && cd.corner == 2 && cd.depth <= size - 1)))) {
			glPushMatrix();
			glTranslate(i * FACET_LENGTH, -i * FACET_LENGTH, i * FACET_LENGTH);
			drawFacet(w, -1, -1, -1, -1, -1, k, -1, -1, tetra); /* 5 */
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner != 0 && cd.depth == size - 1 + s1)
				|| (use && cd.corner == 0 && cd.depth == size - 1 - s1)
				|| (!use && cd.corner != 0 && cd.depth != size - 1 + s1)
				|| (!use && cd.corner == 0 && cd.depth != size - 1 - s1)))
			|| (sticky && ((use && cd.corner != 0 && cd.depth > size - 1)
				|| (use && cd.corner == 0 && cd.depth < size - 1)
				|| (!use && cd.corner != 0 && cd.depth <= size - 1)
				|| (!use && cd.corner == 0 && cd.depth >= size - 1)))) {
			glPushMatrix();
			glTranslate(i * FACET_LENGTH, -i * FACET_LENGTH, -i * FACET_LENGTH);
			drawFacet(w, -1, -1, -1, -1, -1, -1, k, -1, tetra); /* 6 */
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.depth == size - 1 + s1)
				|| (!use && cd.depth != size - 1 + s1)))
			|| (sticky && ((use && cd.depth > size - 1)
				|| (!use && cd.depth <= size - 1)))) {
			glPushMatrix();
			glTranslate(-i * FACET_LENGTH, -i * FACET_LENGTH, -i * FACET_LENGTH);
			drawFacet(w, -1, -1, -1, -1, -1, -1, -1, k, tetra); /* 7 */
			glPopMatrix();
		}
	}
	if (size > 2) { /* CORNERS - 1 */
		s0 = 2 * size - 3;
		j = (size - 1) * (size - 1) + 1; /* 5, */
		k = size * size - 2; /* 7, */
		/* 0 */
		if (all || (!sticky && ((use && cd.corner == 2 && cd.depth == 1)
				|| (use && cd.corner != 2 && cd.depth == size - 1)
				|| (!use && cd.corner == 2 && cd.depth != 1)
				|| (!use && cd.corner != 2 && cd.depth != size - 1)))
			|| (sticky && ((use && cd.corner == 2 && cd.depth < size - 1)
				|| (use && cd.corner != 2 && cd.depth == size - 1)
				|| (!use && cd.corner == 2 && cd.depth >= size - 1)
				|| (!use && cd.corner != 2 && cd.depth != size - 1)))) {
			glPushMatrix();
			glTranslate(FACET_LENGTH, s0 * FACET_LENGTH, -FACET_LENGTH);
			drawTetraFacet(w, 2, -1, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 0 && cd.depth == 1)
				|| (use && cd.corner != 0 && cd.depth == size - 1)
				|| (!use && cd.corner == 0 && cd.depth != 1)
				|| (!use && cd.corner != 0 && cd.depth != size - 1)))
			|| (sticky && ((use && cd.corner == 0 && cd.depth < size - 1)
				|| (use && cd.corner != 0 && cd.depth == size - 1)
				|| (!use && cd.corner == 0 && cd.depth >= size - 1)
				|| (!use && cd.corner != 0 && cd.depth != size - 1)))) {
			glPushMatrix();
			glTranslate(s0 * FACET_LENGTH, FACET_LENGTH, -FACET_LENGTH);
			drawTetraFacet(w, j, -1, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 1 && cd.depth == 2 * size - 3)
				|| (use && cd.corner != 1 && cd.depth == size - 1)
				|| (!use && cd.corner == 1 && cd.depth != 2 * size - 3)
				|| (!use && cd.corner != 1 && cd.depth != size - 1)))
			|| (sticky && ((use && cd.corner == 1 && cd.depth > size - 1)
				|| (use && cd.corner != 1 && cd.depth == size - 1)
				|| (!use && cd.corner == 1 && cd.depth <= size - 1)
				|| (!use && cd.corner != 1 && cd.depth != size - 1)))) {
			glPushMatrix();
			glTranslate(FACET_LENGTH, FACET_LENGTH, -s0 * FACET_LENGTH);
			drawTetraFacet(w, k, -1, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		/* 1 */
		if (all || (!sticky && ((use && cd.corner == 2 && cd.depth == 1)
				|| (use && cd.corner != 2 && cd.depth == size - 1)
				|| (!use && cd.corner == 2 && cd.depth != 1)
				|| (!use && cd.corner != 2 && cd.depth != size - 1)))
			|| (sticky && ((use && cd.corner == 2 && cd.depth < size - 1)
				|| (use && cd.corner != 2 && cd.depth == size - 1)
				|| (!use && cd.corner == 2 && cd.depth >= size - 1)
				|| (!use && cd.corner != 2 && cd.depth != size - 1)))) {
			glPushMatrix();
			glTranslate(FACET_LENGTH, s0 * FACET_LENGTH, FACET_LENGTH);
			drawTetraFacet(w, -1, 2, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 1 && cd.depth == 1)
				|| (use && cd.corner != 1 && cd.depth == size - 1)
				|| (!use && cd.corner == 1 && cd.depth != 1)
				|| (!use && cd.corner != 1 && cd.depth != size - 1)))
			|| (sticky && ((use && cd.corner == 1 && cd.depth < size - 1)
				|| (use && cd.corner != 1 && cd.depth == size - 1)
				|| (!use && cd.corner == 1 && cd.depth >= size - 1)
				|| (!use && cd.corner != 1 && cd.depth != size - 1)))) {
			glPushMatrix();
			glTranslate(FACET_LENGTH, FACET_LENGTH, s0 * FACET_LENGTH);
			drawTetraFacet(w, -1, j, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 0 && cd.depth == 1)
				|| (use && cd.corner != 0 && cd.depth == size - 1)
				|| (!use && cd.corner == 0 && cd.depth != 1)
				|| (!use && cd.corner != 0 && cd.depth != size - 1)))
			|| (sticky && ((use && cd.corner == 0 && cd.depth < size - 1)
				|| (use && cd.corner != 0 && cd.depth == size - 1)
				|| (!use && cd.corner == 0 && cd.depth >= size - 1)
				|| (!use && cd.corner != 0 && cd.depth != size - 1)))) {
			glPushMatrix();
			glTranslate(s0 * FACET_LENGTH, FACET_LENGTH, FACET_LENGTH);
			drawTetraFacet(w, -1, k, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		/* 2 */
		if (all || (!sticky && ((use && cd.corner == 2 && cd.depth == 1)
				|| (use && cd.corner != 2 && cd.depth == size - 1)
				|| (!use && cd.corner == 2 && cd.depth != 1)
				|| (!use && cd.corner != 2 && cd.depth != size - 1)))
			|| (sticky && ((use && cd.corner == 2 && cd.depth < size - 1)
				|| (use && cd.corner != 2 && cd.depth == size - 1)
				|| (!use && cd.corner == 2 && cd.depth >= size - 1)
				|| (!use && cd.corner != 2 && cd.depth != size - 1)))) {
			glPushMatrix();
			glTranslate(-FACET_LENGTH, s0 * FACET_LENGTH, FACET_LENGTH);
			drawTetraFacet(w, -1, -1, 2, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 0 && cd.depth == 2 * size - 3)
				|| (use && cd.corner != 0 && cd.depth == size - 1)
				|| (!use && cd.corner == 0 && cd.depth != 2 * size - 3)
				|| (!use && cd.corner != 0 && cd.depth != size - 1)))
			|| (sticky && ((use && cd.corner == 0 && cd.depth > size - 1)
				|| (use && cd.corner != 0 && cd.depth == size - 1)
				|| (!use && cd.corner == 0 && cd.depth <= size - 1)
				|| (!use && cd.corner != 0 && cd.depth != size - 1)))) {
			glPushMatrix();
			glTranslate(-s0 * FACET_LENGTH, FACET_LENGTH, FACET_LENGTH);
			drawTetraFacet(w, -1, -1, j, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 1 && cd.depth == 1)
				|| (use && cd.corner != 1 && cd.depth == size - 1)
				|| (!use && cd.corner == 1 && cd.depth != 1)
				|| (!use && cd.corner != 1 && cd.depth != size - 1)))
			|| (sticky && ((use && cd.corner == 1 && cd.depth < size - 1)
				|| (use && cd.corner != 1 && cd.depth == size - 1)
				|| (!use && cd.corner == 1 && cd.depth >= size - 1)
				|| (!use && cd.corner != 1 && cd.depth != size - 1)))) {
			glPushMatrix();
			glTranslate(-FACET_LENGTH, FACET_LENGTH, s0 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, k, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		/* 3 */
		if (all || (!sticky && ((use && cd.corner == 2 && cd.depth == 1)
				|| (use && cd.corner != 2 && cd.depth == size - 1)
				|| (!use && cd.corner == 2 && cd.depth != 1)
				|| (!use && cd.corner != 2 && cd.depth != size - 1)))
			|| (sticky && ((use && cd.corner == 2 && cd.depth < size - 1)
				|| (use && cd.corner != 2 && cd.depth == size - 1)
				|| (!use && cd.corner == 2 && cd.depth >= size - 1)
				|| (!use && cd.corner != 2 && cd.depth != size - 1)))) {
			glPushMatrix();
			glTranslate(-FACET_LENGTH, s0 * FACET_LENGTH, -FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, 2, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 1 && cd.depth == 2 * size - 3)
				|| (use && cd.corner != 1 && cd.depth == size - 1)
				|| (!use && cd.corner == 1 && cd.depth != 2 * size - 3)
				|| (!use && cd.corner != 1 && cd.depth != size - 1)))
			|| (sticky && ((use && cd.corner == 1 && cd.depth > size - 1)
				|| (use && cd.corner != 1 && cd.depth == size - 1)
				|| (!use && cd.corner == 1 && cd.depth <= size - 1)
				|| (!use && cd.corner != 1 && cd.depth != size - 1)))) {
			glPushMatrix();
			glTranslate(-FACET_LENGTH, FACET_LENGTH, -s0 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, j, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 0 && cd.depth == 2 * size - 3)
				|| (use && cd.corner != 0 && cd.depth == size - 1)
				|| (!use && cd.corner == 0 && cd.depth != 2 * size - 3)
				|| (!use && cd.corner != 0 && cd.depth != size - 1)))
			|| (sticky && ((use && cd.corner == 0 && cd.depth > size - 1)
				|| (use && cd.corner != 0 && cd.depth == size - 1)
				|| (!use && cd.corner == 0 && cd.depth <= size - 1)
				|| (!use && cd.corner != 0 && cd.depth != size - 1)))) {
			glPushMatrix();
			glTranslate(-s0 * FACET_LENGTH, FACET_LENGTH, -FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, k, -1, -1, -1, -1);
			glPopMatrix();
		}
		/* 4 */
		if (all || (!sticky && ((use && cd.corner == 2 && cd.depth == 2 * size - 3)
				|| (use && cd.corner != 2 && cd.depth == size - 1)
				|| (!use && cd.corner == 2 && cd.depth != 2 * size - 3)
				|| (!use && cd.corner != 2 && cd.depth != size - 1)))
			|| (sticky && ((use && cd.corner == 2 && cd.depth > size - 1)
				|| (use && cd.corner != 2 && cd.depth == size - 1)
				|| (!use && cd.corner == 2 && cd.depth <= size - 1)
				|| (!use && cd.corner != 2 && cd.depth != size - 1)))) {
			glPushMatrix();
			glTranslate(-FACET_LENGTH, -s0 * FACET_LENGTH, FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, 2, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 1 && cd.depth == 1)
				|| (use && cd.corner != 1 && cd.depth == size - 1)
				|| (!use && cd.corner == 1 && cd.depth != 1)
				|| (!use && cd.corner != 1 && cd.depth != size - 1)))
			|| (sticky && ((use && cd.corner == 1 && cd.depth < size - 1)
				|| (use && cd.corner != 1 && cd.depth == size - 1)
				|| (!use && cd.corner == 1 && cd.depth >= size - 1)
				|| (!use && cd.corner != 1 && cd.depth != size - 1)))) {
			glPushMatrix();
			glTranslate(-FACET_LENGTH, -FACET_LENGTH, s0 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, j, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 0 && cd.depth == 2 * size - 3)
				|| (use && cd.corner != 0 && cd.depth == size - 1)
				|| (!use && cd.corner == 0 && cd.depth != 2 * size - 3)
				|| (!use && cd.corner != 0 && cd.depth != size - 1)))
			|| (sticky && ((use && cd.corner == 0 && cd.depth > size - 1)
				|| (use && cd.corner != 0 && cd.depth == size - 1)
				|| (!use && cd.corner == 0 && cd.depth <= size - 1)
				|| (!use && cd.corner != 0 && cd.depth != size - 1)))) {
			glPushMatrix();
			glTranslate(-s0 * FACET_LENGTH, -FACET_LENGTH, FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, k, -1, -1, -1);
			glPopMatrix();
		}
		/* 5 */
		if (all || (!sticky && ((use && cd.corner == 2 && cd.depth == 2 * size - 3)
				|| (use && cd.corner != 2 && cd.depth == size - 1)
				|| (!use && cd.corner == 2 && cd.depth != 2 * size - 3)
				|| (!use && cd.corner != 2 && cd.depth != size - 1)))
			|| (sticky && ((use && cd.corner == 2 && cd.depth > size - 1)
				|| (use && cd.corner != 2 && cd.depth == size - 1)
				|| (!use && cd.corner == 2 && cd.depth <= size - 1)
				|| (!use && cd.corner != 2 && cd.depth != size - 1)))) {
			glPushMatrix();
			glTranslate(FACET_LENGTH, -s0 * FACET_LENGTH, FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, 2, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 0 && cd.depth == 1)
				|| (use && cd.corner != 0 && cd.depth == size - 1)
				|| (!use && cd.corner == 0 && cd.depth != 1)
				|| (!use && cd.corner != 0 && cd.depth != size - 1)))
			|| (sticky && ((use && cd.corner == 0 && cd.depth < size - 1)
				|| (use && cd.corner != 0 && cd.depth == size - 1)
				|| (!use && cd.corner == 0 && cd.depth >= size - 1)
				|| (!use && cd.corner != 0 && cd.depth != size - 1)))) {
			glPushMatrix();
			glTranslate(s0 * FACET_LENGTH, -FACET_LENGTH, FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, j, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 1 && cd.depth == 1)
				|| (use && cd.corner != 1 && cd.depth == size - 1)
				|| (!use && cd.corner == 1 && cd.depth != 1)
				|| (!use && cd.corner != 1 && cd.depth != size - 1)))
			|| (sticky && ((use && cd.corner == 1 && cd.depth < size - 1)
				|| (use && cd.corner != 1 && cd.depth == size - 1)
				|| (!use && cd.corner == 1 && cd.depth >= size - 1)
				|| (!use && cd.corner != 1 && cd.depth != size - 1)))) {
			glPushMatrix();
			glTranslate(FACET_LENGTH, -FACET_LENGTH, s0 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, k, -1, -1);
			glPopMatrix();
		}
		/* 6 */
		if (all || (!sticky && ((use && cd.corner == 2 && cd.depth == 2 * size - 3)
				|| (use && cd.corner != 2 && cd.depth == size - 1)
				|| (!use && cd.corner == 2 && cd.depth != 2 * size - 3)
				|| (!use && cd.corner != 2 && cd.depth != size - 1)))
			|| (sticky && ((use && cd.corner == 2 && cd.depth > size - 1)
				|| (use && cd.corner != 2 && cd.depth == size - 1)
				|| (!use && cd.corner == 2 && cd.depth <= size - 1)
				|| (!use && cd.corner != 2 && cd.depth != size - 1)))) {
			glPushMatrix();
			glTranslate(FACET_LENGTH, -s0 * FACET_LENGTH, -FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, -1, 2, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 1 && cd.depth == 2 * size - 3)
				|| (use && cd.corner != 1 && cd.depth == size - 1)
				|| (!use && cd.corner == 1 && cd.depth != 2 * size - 3)
				|| (!use && cd.corner != 1 && cd.depth != size - 1)))
			|| (sticky && ((use && cd.corner == 1 && cd.depth > size - 1)
				|| (use && cd.corner != 1 && cd.depth == size - 1)
				|| (!use && cd.corner == 1 && cd.depth <= size - 1)
				|| (!use && cd.corner != 1 && cd.depth != size - 1)))) {
			glPushMatrix();
			glTranslate(FACET_LENGTH, -FACET_LENGTH, -s0 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, -1, j, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 0 && cd.depth == 1)
				|| (use && cd.corner != 0 && cd.depth == size - 1)
				|| (!use && cd.corner == 0 && cd.depth != 1)
				|| (!use && cd.corner != 0 && cd.depth != size - 1)))
			|| (sticky && ((use && cd.corner == 0 && cd.depth < size - 1)
				|| (use && cd.corner != 0 && cd.depth == size - 1)
				|| (!use && cd.corner == 0 && cd.depth >= size - 1)
				|| (!use && cd.corner != 0 && cd.depth != size - 1)))) {
			glPushMatrix();
			glTranslate(s0 * FACET_LENGTH, -FACET_LENGTH, -FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, -1, k, -1);
			glPopMatrix();
		}
		/* 7 */
		if (all || (!sticky && ((use && cd.corner == 2 && cd.depth == 2 * size - 3)
				|| (use && cd.corner != 2 && cd.depth == size - 1)
				|| (!use && cd.corner == 2 && cd.depth != 2 * size - 3)
				|| (!use && cd.corner != 2 && cd.depth != size - 1)))
			|| (sticky && ((use && cd.corner == 2 && cd.depth > size - 1)
				|| (use && cd.corner != 2 && cd.depth == size - 1)
				|| (!use && cd.corner == 2 && cd.depth <= size - 1)
				|| (!use && cd.corner != 2 && cd.depth != size - 1)))) {
			glPushMatrix();
			glTranslate(-FACET_LENGTH, -s0 * FACET_LENGTH, -FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, -1, -1, 2);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 0 && cd.depth == 2 * size - 3)
				|| (use && cd.corner != 0 && cd.depth == size - 1)
				|| (!use && cd.corner == 0 && cd.depth != 2 * size - 3)
				|| (!use && cd.corner != 0 && cd.depth != size - 1)))
			|| (sticky && ((use && cd.corner == 0 && cd.depth > size - 1)
				|| (use && cd.corner != 0 && cd.depth == size - 1)
				|| (!use && cd.corner == 0 && cd.depth <= size - 1)
				|| (!use && cd.corner != 0 && cd.depth != size - 1)))) {
			glPushMatrix();
			glTranslate(-s0 * FACET_LENGTH, -FACET_LENGTH, -FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, -1, -1, j);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 1 && cd.depth == 2 * size - 3)
				|| (use && cd.corner != 1 && cd.depth == size - 1)
				|| (!use && cd.corner == 1 && cd.depth != 2 * size - 3)
				|| (!use && cd.corner != 1 && cd.depth != size - 1)))
			|| (sticky && ((use && cd.corner == 1 && cd.depth > size - 1)
				|| (use && cd.corner != 1 && cd.depth == size - 1)
				|| (!use && cd.corner == 1 && cd.depth <= size - 1)
				|| (!use && cd.corner != 1 && cd.depth != size - 1)))) {
			glPushMatrix();
			glTranslate(-FACET_LENGTH, -FACET_LENGTH, -s0* FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, -1, -1, k);
			glPopMatrix();
		}
	}
	if (size > 2 && size % 2 == 1) {
		/* MIDDLE EDGES */ /* 1, 3, 6; 5, 7, 12; 4, 8, 20 */
		int m1 = (size - 1) / 2;
		int e = (3 * size - 3) / 2; /* 3, 6, 9 */
		s1 = size - 1;
		i = (s1 / 2) * (s1 / 2);
		j = (s1 / 2 + 1) * (s1 / 2 + 1) - 1;
		k = size * size - size;
		if (all || (use && cd.corner == 1 && cd.depth == size - 1)
				|| (use && cd.corner != 1 && cd.depth == m1)
				|| (!use && cd.corner == 1 && cd.depth != size - 1)
				|| (!use && cd.corner != 1 && cd.depth != m1)) {
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, s1 * FACET_LENGTH, 0);
			drawOctaFacet(w, i, j, -1, -1, -1, -1, -1, -1); /* 0 */
			glPopMatrix();
		}
		if (all || (use && cd.corner == 0 && cd.depth == size - 1)
				|| (use && cd.corner != 0 && cd.depth == m1)
				|| (!use && cd.corner == 0 && cd.depth != size - 1)
				|| (!use && cd.corner != 0 && cd.depth != m1)) {
			glPushMatrix();
			glTranslate(0, s1 * FACET_LENGTH, s1 * FACET_LENGTH);
			drawOctaFacet(w, -1, i, j, -1, -1, -1, -1, -1); /* 1 */
			glPopMatrix();
		}
		if (all || (use && cd.corner == 1 && cd.depth == size - 1)
				|| (use && cd.corner == 2 && cd.depth == m1)
				|| (use && cd.corner == 0 && cd.depth == e)
				|| (!use && cd.corner == 1 && cd.depth != size - 1)
				|| (!use && cd.corner == 2 && cd.depth != m1)
				|| (!use && cd.corner == 0 && cd.depth != e)) {
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, s1 * FACET_LENGTH, 0);
			drawOctaFacet(w, -1, -1, i, j, -1, -1, -1, -1); /* 2 */
			glPopMatrix();
		}
		if (all || (use && cd.corner == 0 && cd.depth == size - 1)
				|| (use && cd.corner == 2 && cd.depth == m1)
				|| (use && cd.corner == 1 && cd.depth == e)
				|| (!use && cd.corner == 0 && cd.depth != size - 1)
				|| (!use && cd.corner == 2 && cd.depth != m1)
				|| (!use && cd.corner == 1 && cd.depth != e)) {
			glPushMatrix();
			glTranslate(0, s1 * FACET_LENGTH, -s1 * FACET_LENGTH);
			drawOctaFacet(w, j, -1, -1, i, -1, -1, -1, -1); /* 3 */
			glPopMatrix();
		}
		if (all || (use && cd.corner == 0 && cd.depth == size - 1)
				|| (use && cd.corner == 1 && cd.depth == m1)
				|| (use && cd.corner == 2 && cd.depth == e)
				|| (!use && cd.corner == 0 && cd.depth != size - 1)
				|| (!use && cd.corner == 1 && cd.depth != m1)
				|| (!use && cd.corner == 2 && cd.depth != e)) {
			glPushMatrix();
			glTranslate(0, -s1 * FACET_LENGTH, s1 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, -1, -1, i, j, -1, -1); /* 9 */
			glPopMatrix();
		}
		if (all || (use && cd.corner == 1 && cd.depth == size - 1)
				|| (use && cd.corner == 0 && cd.depth == m1)
				|| (use && cd.corner == 2 && cd.depth == e)
				|| (!use && cd.corner == 1 && cd.depth != size - 1)
				|| (!use && cd.corner == 0 && cd.depth != m1)
				|| (!use && cd.corner == 2 && cd.depth != e)) {
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, -s1 * FACET_LENGTH, 0);
			drawOctaFacet(w, -1, -1, -1, -1, -1, i, j, -1); /* 10 */
			glPopMatrix();
		}
		if (all || (use && cd.corner == 0 && cd.depth == size - 1)
				|| (use && cd.corner != 0 && cd.depth == e)
				|| (!use && cd.corner == 0 && cd.depth != size - 1)
				|| (!use && cd.corner != 0 && cd.depth != e)) {
			glPushMatrix();
			glTranslate(0, -s1 * FACET_LENGTH, -s1 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, -1, -1, -1, -1, i, j); /* 11 */
			glPopMatrix();
		}
		if (all || (use && cd.corner == 1 && cd.depth == size - 1)
				|| (use && cd.corner != 1 && cd.depth == e)
				|| (!use && cd.corner == 1 && cd.depth != size - 1)
				|| (!use && cd.corner != 1 && cd.depth != e)) {
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, -s1 * FACET_LENGTH, 0);
			drawOctaFacet(w, -1, -1, -1, -1, j, -1, -1, i); /* 12 */
			glPopMatrix();
		}
		if (all || (use && cd.corner == 2 && cd.depth == size - 1)
				|| (use && cd.corner == 0 && cd.depth == m1)
				|| (use && cd.corner == 1 && cd.depth == e)
				|| (!use && cd.corner == 2 && cd.depth != size - 1)
				|| (!use && cd.corner == 0 && cd.depth != m1)
				|| (!use && cd.corner == 1 && cd.depth != e)) {
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, 0, -s1 * FACET_LENGTH);
			drawOctaFacet(w, k, -1, -1, -1, -1, -1, k, -1); /* 4 */
			glPopMatrix();
		}
		if (all || (use && cd.corner == 2 && cd.depth == size - 1)
				|| (use && cd.corner != 2 && cd.depth == m1)
				|| (!use && cd.corner == 2 && cd.depth != size - 1)
				|| (!use && cd.corner != 2 && cd.depth != m1)) {
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, 0, s1 * FACET_LENGTH);
			drawOctaFacet(w, -1, k, -1, -1, -1, k, -1, -1); /* 5 */
			glPopMatrix();
		}
		if (all || (use && cd.corner == 2 && cd.depth == size - 1)
				|| (use && cd.corner == 1 && cd.depth == m1)
				|| (use && cd.corner == 0 && cd.depth == e)
				|| (!use && cd.corner == 2 && cd.depth != size - 1)
				|| (!use && cd.corner == 1 && cd.depth != m1)
				|| (!use && cd.corner == 0 && cd.depth != e)) {
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, 0, s1 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, k, -1, k, -1, -1, -1); /* 6 */
			glPopMatrix();
		}
		if (all || (use && cd.corner == 2 && cd.depth == size - 1)
				|| (use && cd.corner != 2 && cd.depth == e)
				|| (!use && cd.corner == 2 && cd.depth != size - 1)
				|| (!use && cd.corner != 2 && cd.depth != e)) {
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, 0, -s1 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, -1, k, -1, -1, -1, k); /* 7 */
			glPopMatrix();
		}
	} else if (size > 2 && size % 2 == 0) {
		/* EDGES - 1 */
		int m = size / 2;
		int e = 2 * size - 2 - m;
		s1 = size - 1;
		i = (size / 2) * (size / 2) + 1;
		j = (size / 2 + 1) * (size / 2 + 1) - 2;
		k = size * size - size;
		/* 0 */
		if (all || (!sticky && ((use && cd.corner == 1 && cd.depth == size - 1)
				|| (use && cd.corner != 1 && cd.depth == m)
				|| (!use && cd.corner == 1 && cd.depth != size - 1)
				|| (!use && cd.corner != 1 && cd.depth != m)))
			|| (sticky && ((use && cd.corner == 1 && cd.depth == size - 1)
				|| (use && cd.corner != 1 && cd.depth < size - 1)
				|| (!use && cd.corner == 1 && cd.depth != size - 1)
				|| (!use && cd.corner != 1 && cd.depth >= size - 1)))) {
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, s1 * FACET_LENGTH, -FACET_LENGTH);
			drawTetraFacet(w, i, -1, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 0 && cd.depth == size - 1)
				|| (use && cd.corner == 1 && cd.depth == e) 
				|| (use && cd.corner == 2 && cd.depth == m)
				|| (!use && cd.corner == 0 && cd.depth != size - 1)
				|| (!use && cd.corner == 1 && cd.depth != e)
				|| (!use && cd.corner == 2 && cd.depth != m)))
			|| (sticky && ((use && cd.corner == 0 && cd.depth == size - 1)
				|| (use && cd.corner == 1 && cd.depth > size - 1)
				|| (use && cd.corner == 2 && cd.depth < size - 1)
				|| (!use && cd.corner == 0 && cd.depth != size - 1)
				|| (!use && cd.corner == 1 && cd.depth <= size - 1)
				|| (!use && cd.corner == 2 && cd.depth >= size - 1)))) {
			glPushMatrix();
			glTranslate(FACET_LENGTH, s1 * FACET_LENGTH, -s1 * FACET_LENGTH);
			drawTetraFacet(w, j, -1, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 2 && cd.depth == size - 1)
				|| (use && cd.corner == 1 && cd.depth == e)
				|| (use && cd.corner == 0 && cd.depth == m)
				|| (!use && cd.corner == 2 && cd.depth != size - 1)
				|| (!use && cd.corner == 1 && cd.depth != e)
				|| (!use && cd.corner == 0 && cd.depth != m)))
			|| (sticky && ((use && cd.corner == 2 && cd.depth == size - 1)
				|| (use && cd.corner == 1 && cd.depth > size - 1)
				|| (use && cd.corner == 0 && cd.depth < size - 1)
				|| (!use && cd.corner == 2 && cd.depth != size - 1)
				|| (!use && cd.corner == 1 && cd.depth <= size - 1)
				|| (!use && cd.corner == 0 && cd.depth >= size - 1)))) {
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, FACET_LENGTH, -s1 * FACET_LENGTH);
			drawTetraFacet(w, k, -1, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		/* 1 */
		if (all || (!sticky && ((use && cd.corner == 0 && cd.depth == size - 1)
				|| (use && cd.corner != 0 && cd.depth == m)
				|| (!use && cd.corner == 0 && cd.depth != size - 1)
				|| (!use && cd.corner != 0 && cd.depth != m)))
			|| (sticky && ((use && cd.corner == 0 && cd.depth == size - 1)
				|| (use && cd.corner != 0 && cd.depth < size - 1)
				|| (!use && cd.corner == 0 && cd.depth != size - 1)
				|| (!use && cd.corner != 0 && cd.depth >= size - 1)))) {
			glPushMatrix();
			glTranslate(FACET_LENGTH, s1 * FACET_LENGTH, s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, i, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 1 && cd.depth == size - 1)
				|| (use && cd.corner != 1 && cd.depth == m)
				|| (!use && cd.corner == 1 && cd.depth != size - 1)
				|| (!use && cd.corner != 1 && cd.depth != m)))
			|| (sticky && ((use && cd.corner == 1 && cd.depth == size - 1)
				|| (use && cd.corner != 1 && cd.depth < size - 1)
				|| (!use && cd.corner == 1 && cd.depth != size - 1)
				|| (!use && cd.corner != 1 && cd.depth >= size - 1)))) {
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, s1 * FACET_LENGTH, FACET_LENGTH);
			drawTetraFacet(w, -1, j, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 2 && cd.depth == size - 1)
				|| (use && cd.corner != 2 && cd.depth == m)
				|| (!use && cd.corner == 2 && cd.depth != size - 1)
				|| (!use && cd.corner != 2 && cd.depth != m)))
			|| (sticky && ((use && cd.corner == 2 && cd.depth == size - 1)
				|| (use && cd.corner != 2 && cd.depth < size - 1)
				|| (!use && cd.corner == 2 && cd.depth != size - 1)
				|| (!use && cd.corner != 2 && cd.depth >= size - 1)))) {
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, FACET_LENGTH, s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, k, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		/* 2 */
		if (all || (!sticky && ((use && cd.corner == 1 && cd.depth == size - 1)
				|| (use && cd.corner == 0 && cd.depth == e)
				|| (use && cd.corner == 2 && cd.depth == m)
				|| (!use && cd.corner == 1 && cd.depth != size - 1)
				|| (!use && cd.corner == 0 && cd.depth != e)
				|| (!use && cd.corner == 2 && cd.depth != m)))
			|| (sticky && ((use && cd.corner == 1 && cd.depth == size - 1)
				|| (use && cd.corner == 0 && cd.depth > size - 1)
				|| (use && cd.corner == 2 && cd.depth < size - 1)
				|| (!use && cd.corner == 1 && cd.depth != size - 1)
				|| (!use && cd.corner == 0 && cd.depth <= size - 1)
				|| (!use && cd.corner == 2 && cd.depth >= size - 1)))) {
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, s1 * FACET_LENGTH, FACET_LENGTH);
			drawTetraFacet(w, -1, -1, i, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 0 && cd.depth == size - 1)
				|| (use && cd.corner != 0 && cd.depth == m)
				|| (!use && cd.corner == 0 && cd.depth != size - 1)
				|| (!use && cd.corner != 0 && cd.depth != m)))
			|| (sticky && ((use && cd.corner == 0 && cd.depth == size - 1)
				|| (use && cd.corner != 0 && cd.depth < size - 1)
				|| (!use && cd.corner == 0 && cd.depth != size - 1)
				|| (!use && cd.corner != 0 && cd.depth >= size - 1)))) {
			glPushMatrix();
			glTranslate(-FACET_LENGTH, s1 * FACET_LENGTH, s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, j, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 2 && cd.depth == size - 1)
				|| (use && cd.corner == 0 && cd.depth == e)
				|| (use && cd.corner == 1 && cd.depth == m)
				|| (!use && cd.corner == 2 && cd.depth != size - 1)
				|| (!use && cd.corner == 0 && cd.depth != e)
				|| (!use && cd.corner == 1 && cd.depth != m)))
			|| (sticky && ((use && cd.corner == 2 && cd.depth == size - 1)
				|| (use && cd.corner == 0 && cd.depth > size - 1)
				|| (use && cd.corner == 1 && cd.depth < size - 1)
				|| (!use && cd.corner == 2 && cd.depth != size - 1)
				|| (!use && cd.corner == 0 && cd.depth <= size - 1)
				|| (!use && cd.corner == 1 && cd.depth >= size - 1)))) {
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, FACET_LENGTH, s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, k, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		/* 3 */
		if (all || (!sticky && ((use && cd.corner == 0 && cd.depth == size - 1)
				|| (use && cd.corner == 1 && cd.depth == e)
				|| (use && cd.corner == 2 && cd.depth == m)
				|| (!use && cd.corner == 0 && cd.depth != size - 1)
				|| (!use && cd.corner == 1 && cd.depth != e)
				|| (!use && cd.corner == 2 && cd.depth != m)))
			|| (sticky && ((use && cd.corner == 0 && cd.depth == size - 1)
				|| (use && cd.corner == 1 && cd.depth > size - 1)
				|| (use && cd.corner == 2 && cd.depth < size - 1)
				|| (!use && cd.corner == 0 && cd.depth != size - 1)
				|| (!use && cd.corner == 1 && cd.depth <= size - 1)
				|| (!use && cd.corner == 2 && cd.depth >= size - 1)))) {
			glPushMatrix();
			glTranslate(-FACET_LENGTH, s1 * FACET_LENGTH, -s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, i, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 1 && cd.depth == size - 1)
				|| (use && cd.corner == 0 && cd.depth == e)
				|| (use && cd.corner == 2 && cd.depth == m)
				|| (!use && cd.corner == 1 && cd.depth != size - 1)
				|| (!use && cd.corner == 0 && cd.depth != e)
				|| (!use && cd.corner == 2 && cd.depth != m)))
			|| (sticky && ((use && cd.corner == 1 && cd.depth == size - 1)
				|| (use && cd.corner == 0 && cd.depth > size - 1)
				|| (use && cd.corner == 2 && cd.depth < size - 1)
				|| (!use && cd.corner == 1 && cd.depth != size - 1)
				|| (!use && cd.corner == 0 && cd.depth <= size - 1)
				|| (!use && cd.corner == 2 && cd.depth >= size - 1)))) {
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, s1 * FACET_LENGTH, -FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, j, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 2 && cd.depth == size - 1)
				|| (use && cd.corner != 2 && cd.depth == e)
				|| (!use && cd.corner == 2 && cd.depth != size - 1)
				|| (!use && cd.corner != 2 && cd.depth != e)))
			|| (sticky && ((use && cd.corner == 2 && cd.depth == size - 1)
				|| (use && cd.corner != 2 && cd.depth > size - 1)
				|| (!use && cd.corner == 2 && cd.depth != size - 1)
				|| (!use && cd.corner != 2 && cd.depth <= size - 1)))) {
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, FACET_LENGTH, -s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, k, -1, -1, -1, -1);
			glPopMatrix();
		}
		/* 4 */
		if (all || (!sticky && ((use && cd.corner == 0 && cd.depth == size - 1)
				|| (use && cd.corner == 2 && cd.depth == e)
				|| (use && cd.corner == 1 && cd.depth == m)
				|| (!use && cd.corner == 0 && cd.depth != size - 1)
				|| (!use && cd.corner == 2 && cd.depth != e)
				|| (!use && cd.corner == 1 && cd.depth != m)))
			|| (sticky && ((use && cd.corner == 0 && cd.depth == size - 1)
				|| (use && cd.corner == 2 && cd.depth > size - 1)
				|| (use && cd.corner == 1 && cd.depth < size - 1)
				|| (!use && cd.corner == 0 && cd.depth != size - 1)
				|| (!use && cd.corner == 2 && cd.depth <= size - 1)
				|| (!use && cd.corner == 1 && cd.depth >= size - 1)))) {
			glPushMatrix();
			glTranslate(-FACET_LENGTH, -s1 * FACET_LENGTH, s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, i, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 1 && cd.depth == size - 1)
				|| (use && cd.corner != 1 && cd.depth == e)
				|| (!use && cd.corner == 1 && cd.depth != size - 1)
				|| (!use && cd.corner != 1 && cd.depth != e)))
			|| (sticky && ((use && cd.corner == 1 && cd.depth == size - 1)
				|| (use && cd.corner != 1 && cd.depth > size - 1)
				|| (!use && cd.corner == 1 && cd.depth != size - 1)
				|| (!use && cd.corner != 1 && cd.depth <= size - 1)))) {
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, -s1 * FACET_LENGTH, FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, j, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 2 && cd.depth == size - 1)
				|| (use && cd.corner == 0 && cd.depth == e)
				|| (use && cd.corner == 1 && cd.depth == m)
				|| (!use && cd.corner == 2 && cd.depth != size - 1)
				|| (!use && cd.corner == 0 && cd.depth != e)
				|| (!use && cd.corner == 1 && cd.depth != m)))
			|| (sticky && ((use && cd.corner == 2 && cd.depth == size - 1)
				|| (use && cd.corner == 0 && cd.depth > size - 1)
				|| (use && cd.corner == 1 && cd.depth < size - 1)
				|| (!use && cd.corner == 2 && cd.depth != size - 1)
				|| (!use && cd.corner == 0 && cd.depth <= size - 1)
				|| (!use && cd.corner == 1 && cd.depth >= size - 1)))) {
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, -FACET_LENGTH, s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, k, -1, -1, -1);
			glPopMatrix();
		}
		/* 5 */
		if (all || (!sticky && ((use && cd.corner == 1 && cd.depth == size - 1)
				|| (use && cd.corner == 2 && cd.depth == e)
				|| (use && cd.corner == 0 && cd.depth == m)
				|| (!use && cd.corner == 1 && cd.depth != size - 1)
				|| (!use && cd.corner == 2 && cd.depth != e)
				|| (!use && cd.corner == 0 && cd.depth != m)))
			|| (sticky && ((use && cd.corner == 1 && cd.depth == size - 1)
				|| (use && cd.corner == 2 && cd.depth > size - 1)
				|| (use && cd.corner == 0 && cd.depth < size - 1)
				|| (!use && cd.corner == 1 && cd.depth != size - 1)
				|| (!use && cd.corner == 2 && cd.depth <= size - 1)
				|| (!use && cd.corner == 0 && cd.depth >= size - 1)))) {
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, -s1 * FACET_LENGTH, FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, i, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 0 && cd.depth == size - 1)
				|| (use && cd.corner == 2 && cd.depth == e)
				|| (use && cd.corner == 1 && cd.depth == m)
				|| (!use && cd.corner == 0 && cd.depth != size - 1)
				|| (!use && cd.corner == 2 && cd.depth != e)
				|| (!use && cd.corner == 1 && cd.depth != m)))
			|| (sticky && ((use && cd.corner == 0 && cd.depth == size - 1)
				|| (use && cd.corner == 2 && cd.depth > size - 1)
				|| (use && cd.corner == 1 && cd.depth < size - 1)
				|| (!use && cd.corner == 0 && cd.depth != size - 1)
				|| (!use && cd.corner == 2 && cd.depth <= size - 1)
				|| (!use && cd.corner == 1 && cd.depth >= size - 1)))) {
			glPushMatrix();
			glTranslate(FACET_LENGTH, -s1 * FACET_LENGTH, s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, j, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 2 && cd.depth == size - 1)
				|| (use && cd.corner != 2 && cd.depth == m)
				|| (!use && cd.corner == 2 && cd.depth != size - 1)
				|| (!use && cd.corner != 2 && cd.depth != m)))
			|| (sticky && ((use && cd.corner == 2 && cd.depth == size - 1)
				|| (use && cd.corner != 2 && cd.depth < size - 1)
				|| (!use && cd.corner == 2 && cd.depth != size - 1)
				|| (!use && cd.corner != 2 && cd.depth >= size - 1)))) {
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, -FACET_LENGTH, s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, k, -1, -1);
			glPopMatrix();
		}
		/* 6 */
		if (all || (!sticky && ((use && cd.corner == 0 && cd.depth == size - 1)
				|| (use && cd.corner != 0 && cd.depth == e)
				|| (!use && cd.corner == 0 && cd.depth != size - 1)
				|| (!use && cd.corner != 0 && cd.depth != e)))
			|| (sticky && ((use && cd.corner == 0 && cd.depth == size - 1)
				|| (use && cd.corner != 0 && cd.depth > size - 1)
				|| (!use && cd.corner == 0 && cd.depth != size - 1)
				|| (!use && cd.corner != 0 && cd.depth <= size - 1)))) {
			glPushMatrix();
			glTranslate(FACET_LENGTH, -s1 * FACET_LENGTH, -s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, -1, i, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 1 && cd.depth == size - 1)
				|| (use && cd.corner == 2 && cd.depth == e)
				|| (use && cd.corner == 0 && cd.depth == m)
				|| (!use && cd.corner == 1 && cd.depth != size - 1)
				|| (!use && cd.corner == 2 && cd.depth != e)
				|| (!use && cd.corner == 0 && cd.depth != m)))
			|| (sticky && ((use && cd.corner == 1 && cd.depth == size - 1)
				|| (use && cd.corner == 2 && cd.depth > size - 1)
				|| (use && cd.corner == 0 && cd.depth < size - 1)
				|| (!use && cd.corner == 1 && cd.depth != size - 1)
				|| (!use && cd.corner == 2 && cd.depth <= size - 1)
				|| (!use && cd.corner == 0 && cd.depth >= size - 1)))) {
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, -s1 * FACET_LENGTH, -FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, -1, j, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 2 && cd.depth == size - 1)
				|| (use && cd.corner == 1 && cd.depth == e)
				|| (use && cd.corner == 0 && cd.depth == m)
				|| (!use && cd.corner == 2 && cd.depth != size - 1)
				|| (!use && cd.corner == 1 && cd.depth != e)
				|| (!use && cd.corner == 0 && cd.depth != m)))
			|| (sticky && ((use && cd.corner == 2 && cd.depth == size - 1)
				|| (use && cd.corner == 1 && cd.depth > size - 1)
				|| (use && cd.corner == 0 && cd.depth < size - 1)
				|| (!use && cd.corner == 2 && cd.depth != size - 1)
				|| (!use && cd.corner == 1 && cd.depth <= size - 1)
				|| (!use && cd.corner == 0 && cd.depth >= size - 1)))) {
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, -FACET_LENGTH, -s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, -1, k, -1);
			glPopMatrix();
		}
		/* 7 */
		if (all || (!sticky && ((use && cd.corner == 1 && cd.depth == size - 1)
				|| (use && cd.corner != 1 && cd.depth == e)
				|| (!use && cd.corner == 1 && cd.depth != size - 1)
				|| (!use && cd.corner != 1 && cd.depth != e)))
			|| (sticky && ((use && cd.corner == 1 && cd.depth == size - 1)
				|| (use && cd.corner != 1 && cd.depth > size - 1)
				|| (!use && cd.corner == 1 && cd.depth != size - 1)
				|| (!use && cd.corner != 1 && cd.depth <= size - 1)))) {
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, -s1 * FACET_LENGTH, -FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, -1, -1, i);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 0 && cd.depth == size - 1)
				|| (use && cd.corner != 0 && cd.depth == e)
				|| (!use && cd.corner == 0 && cd.depth != size - 1)
				|| (!use && cd.corner != 0 && cd.depth != e)))
			|| (sticky && ((use && cd.corner == 0 && cd.depth == size - 1)
				|| (use && cd.corner != 0 && cd.depth > size - 1)
				|| (!use && cd.corner == 0 && cd.depth != size - 1)
				|| (!use && cd.corner != 0 && cd.depth <= size - 1)))) {
			glPushMatrix();
			glTranslate(-FACET_LENGTH, -s1 * FACET_LENGTH, -s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, -1, -1, j);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 2 && cd.depth == size - 1)
				|| (use && cd.corner != 2 && cd.depth == e)
				|| (!use && cd.corner == 2 && cd.depth != size - 1)
				|| (!use && cd.corner != 2 && cd.depth != e)))
			|| (sticky && ((use && cd.corner == 2 && cd.depth == size - 1)
				|| (use && cd.corner != 2 && cd.depth > size - 1)
				|| (!use && cd.corner == 2 && cd.depth != size - 1)
				|| (!use && cd.corner != 2 && cd.depth <= size - 1)))) {
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, -FACET_LENGTH, -s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, -1, -1, k);
			glPopMatrix();
		}
	}
	if (size > 3) { /* EDGE 1 */
		int a, b, c, d, e, f;
		int m1 = 1;
		int s3 = size - 2;
		s0 = 2 * size - 4;
		s1 = size - 1;
		s2 = 2;
		a = 1;
		b = 3;
		c = s3 * s3;
		d = s1 * s1 - 1;
		e = s1 * s1 + 2;
		f = size * size - 3;
		if (all || (!sticky && ((use && cd.corner == 1 && cd.depth == size - 1)
				|| (use && cd.corner == 0 && cd.depth == size - 1 - m1)
				|| (use && cd.corner == 2 && cd.depth == m1)
				|| (!use && cd.corner == 1 && cd.depth != size - 1)
				|| (!use && cd.corner == 0 && cd.depth != size - 1 - m1)
				|| (!use && cd.corner == 2 && cd.depth != m1)))
			|| (sticky && ((use && cd.corner == 1 && cd.depth == size - 1)
				|| (use && cd.corner != 1 && cd.depth < size - 1)
				|| (!use && cd.corner == 1 && cd.depth != size - 1)
				|| (!use && cd.corner != 1 && cd.depth >= size - 1)))) {
			glPushMatrix();
			glTranslate(s2 * FACET_LENGTH, s0 * FACET_LENGTH, 0);
			drawOctaFacet(w, a, b, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 0 && cd.depth == size - 1)
				|| (use && cd.corner == 1 && cd.depth == size - 1 - m1)
				|| (use && cd.corner == 2 && cd.depth == m1)
				|| (!use && cd.corner == 0 && cd.depth != size - 1)
				|| (!use && cd.corner == 1 && cd.depth != size - 1 - m1)
				|| (!use && cd.corner == 2 && cd.depth != m1)))
			|| (sticky && ((use && cd.corner == 0 && cd.depth == size - 1)
				|| (use && cd.corner != 0 && cd.depth < size - 1)
				|| (!use && cd.corner == 0 && cd.depth != size - 1)
				|| (!use && cd.corner != 0 && cd.depth >= size - 1)))) {
			glPushMatrix();
			glTranslate(0, s0 * FACET_LENGTH, s2 * FACET_LENGTH);
			drawOctaFacet(w, -1, a, b, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 1 && cd.depth == size - 1)
				|| (use && cd.corner == 0 && cd.depth == size)
				|| (use && cd.corner == 2 && cd.depth == m1)
				|| (!use && cd.corner == 1 && cd.depth != size - 1)
				|| (!use && cd.corner == 0 && cd.depth != size)
				|| (!use && cd.corner == 2 && cd.depth != m1)))
			|| (sticky && ((use && cd.corner == 1 && cd.depth == size - 1)
				|| (use && cd.corner == 0 && cd.depth > size - 1)
				|| (use && cd.corner == 2 && cd.depth < size - 1)
				|| (!use && cd.corner == 1 && cd.depth != size - 1)
				|| (!use && cd.corner == 0 && cd.depth <= size - 1)
				|| (!use && cd.corner == 2 && cd.depth >= size - 1)))) {
			glPushMatrix();
			glTranslate(-s2 * FACET_LENGTH, s0 * FACET_LENGTH, 0);
			drawOctaFacet(w, -1, -1, a, b, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 0 && cd.depth == size - 1)
				|| (use && cd.corner == 1 && cd.depth == size)
				|| (use && cd.corner == 2 && cd.depth == m1)
				|| (!use && cd.corner == 0 && cd.depth != size - 1)
				|| (!use && cd.corner == 1 && cd.depth != size)
				|| (!use && cd.corner == 2 && cd.depth != m1)))
			|| (sticky && ((use && cd.corner == 0 && cd.depth == size - 1)
				|| (use && cd.corner == 1 && cd.depth > size - 1)
				|| (use && cd.corner == 2 && cd.depth < size - 1)
				|| (!use && cd.corner == 0 && cd.depth != size - 1)
				|| (!use && cd.corner == 1 && cd.depth <= size - 1)
				|| (!use && cd.corner == 2 && cd.depth >= size - 1)))) {
			glPushMatrix();
			glTranslate(0, s0 * FACET_LENGTH, -s2 * FACET_LENGTH);
			drawOctaFacet(w, b, -1, -1, a, -1, -1, -1, -1);
			glPopMatrix();
		}

		if (all || (!sticky && ((use && cd.corner == 0 && cd.depth == size - 1)
				|| (use && cd.corner == 1 && cd.depth == size - 1 - m1)
				|| (use && cd.corner == 2 && cd.depth == 2 * size - 2 - m1)
				|| (!use && cd.corner == 0 && cd.depth != size - 1)
				|| (!use && cd.corner == 1 && cd.depth != size - 1 - m1)
				|| (!use && cd.corner == 2 && cd.depth != 2 * size - 2 - m1)))
			|| (sticky && ((use && cd.corner == 0 && cd.depth == size - 1)
				|| (use && cd.corner == 1 && cd.depth < size - 1)
				|| (use && cd.corner == 2 && cd.depth > size - 1)
				|| (!use && cd.corner == 0 && cd.depth != size - 1)
				|| (!use && cd.corner == 1 && cd.depth >= size - 1)
				|| (!use && cd.corner == 2 && cd.depth <= size - 1)))) {
			glPushMatrix();
			glTranslate(0, -s0 * FACET_LENGTH, s2 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, -1, -1, a, b, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 1 && cd.depth == size - 1)
				|| (use && cd.corner == 0 && cd.depth == size - 1 - m1)
				|| (use && cd.corner == 2 && cd.depth == 2 * size - 2 - m1)
				|| (!use && cd.corner == 1 && cd.depth != size - 1)
				|| (!use && cd.corner == 0 && cd.depth != size - 1 - m1)
				|| (!use && cd.corner == 2 && cd.depth != 2 * size - 2 - m1)))
			|| (sticky && ((use && cd.corner == 1 && cd.depth == size - 1)
				|| (use && cd.corner == 0 && cd.depth < size - 1)
				|| (use && cd.corner == 2 && cd.depth > size - 1)
				|| (!use && cd.corner == 1 && cd.depth != size - 1)
				|| (!use && cd.corner == 0 && cd.depth >= size - 1)
				|| (!use && cd.corner == 2 && cd.depth <= size - 1)))) {
			glPushMatrix();
			glTranslate(s2 * FACET_LENGTH, -s0 * FACET_LENGTH, 0);
			drawOctaFacet(w, -1, -1, -1, -1, -1, a, b, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 0 && cd.depth == size - 1)
				|| (use && cd.corner == 1 && cd.depth == size)
				|| (use && cd.corner == 2 && cd.depth == 2 * size - 2 - m1)
				|| (!use && cd.corner == 0 && cd.depth != size - 1)
				|| (!use && cd.corner == 1 && cd.depth != size)
				|| (!use && cd.corner == 2 && cd.depth != 2 * size - 2 - m1)))
			|| (sticky && ((use && cd.corner == 0 && cd.depth == size - 1)
				|| (use && cd.corner != 0 && cd.depth > size - 1)
				|| (!use && cd.corner == 0 && cd.depth != size - 1)
				|| (!use && cd.corner != 0 && cd.depth <= size - 1)))) {
			glPushMatrix();
			glTranslate(0, -s0 * FACET_LENGTH, -s2 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, -1, -1, -1, -1, a, b);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 1 && cd.depth == size - 1)
				|| (use && cd.corner == 0 && cd.depth == size)
				|| (use && cd.corner == 2 && cd.depth == 2 * size - 2 - m1)
				|| (!use && cd.corner == 1 && cd.depth != size - 1)
				|| (!use && cd.corner == 0 && cd.depth != size)
				|| (!use && cd.corner == 2 && cd.depth != 2 * size - 2 - m1)))
			|| (sticky && ((use && cd.corner == 1 && cd.depth == size - 1)
				|| (use && cd.corner != 1 && cd.depth > size - 1)
				|| (!use && cd.corner == 1 && cd.depth != size - 1)
				|| (!use && cd.corner != 1 && cd.depth <= size - 1)))) {
			glPushMatrix();
			glTranslate(-s2 * FACET_LENGTH, -s0 * FACET_LENGTH, 0);
			drawOctaFacet(w, -1, -1, -1, -1, b, -1, -1, a);
			glPopMatrix();
		}

		if (all || (!sticky && ((use && cd.corner == 1 && cd.depth == size - 1)
				|| (use && cd.corner == 0 && cd.depth == m1)
				|| (use && cd.corner == 2 && cd.depth == size - 1 - m1)
				|| (!use && cd.corner == 1 && cd.depth != size - 1)
				|| (!use && cd.corner == 0 && cd.depth != m1)
				|| (!use && cd.corner == 2 && cd.depth != size - 1 - m1)))
			|| (sticky && ((use && cd.corner == 1 && cd.depth == size - 1)
				|| (use && cd.corner != 1 && cd.depth < size - 1)
				|| (!use && cd.corner == 1 && cd.depth != size - 1)
				|| (!use && cd.corner != 1 && cd.depth >= size - 1)))) {
			glPushMatrix();
			glTranslate(s0 * FACET_LENGTH, s2 * FACET_LENGTH, 0);
			drawOctaFacet(w, c, d, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 0 && cd.depth == size - 1)
				|| (use && cd.corner == 1 && cd.depth == m1)
				|| (use && cd.corner == 2 && cd.depth == size - 1 - m1)
				|| (!use && cd.corner == 0 && cd.depth != size - 1)
				|| (!use && cd.corner == 1 && cd.depth != m1)
				|| (!use && cd.corner == 2 && cd.depth != size - 1 - m1)))
			|| (sticky && ((use && cd.corner == 0 && cd.depth == size - 1)
				|| (use && cd.corner != 0 && cd.depth < size - 1)
				|| (!use && cd.corner == 0 && cd.depth != size - 1)
				|| (!use && cd.corner != 0 && cd.depth >= size - 1)))) {
			glPushMatrix();
			glTranslate(0, s2 * FACET_LENGTH, s0 * FACET_LENGTH);
			drawOctaFacet(w, -1, c, d, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 1 && cd.depth == size - 1)
				|| (use && cd.corner == 0 && cd.depth == 2 * size - 2 - m1)
				|| (use && cd.corner == 2 && cd.depth == size - 1 - m1)
				|| (!use && cd.corner == 1 && cd.depth != size - 1)
				|| (!use && cd.corner == 0 && cd.depth != 2 * size - 2 - m1)
				|| (!use && cd.corner == 2 && cd.depth != size - 1 - m1)))
			|| (sticky && ((use && cd.corner == 1 && cd.depth == size - 1)
				|| (use && cd.corner == 0 && cd.depth > size - 1)
				|| (use && cd.corner == 2 && cd.depth < size - 1)
				|| (!use && cd.corner == 1 && cd.depth != size - 1)
				|| (!use && cd.corner == 0 && cd.depth <= size - 1)
				|| (!use && cd.corner == 2 && cd.depth >= size - 1)))) {
			glPushMatrix();
			glTranslate(-s0 * FACET_LENGTH, s2 * FACET_LENGTH, 0);
			drawOctaFacet(w, -1, -1, c, d, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 0 && cd.depth == size - 1)
				|| (use && cd.corner == 1 && cd.depth == 2 * size - 2 - m1)
				|| (use && cd.corner == 2 && cd.depth == size - 1 - m1)
				|| (!use && cd.corner == 0 && cd.depth != size - 1)
				|| (!use && cd.corner == 1 && cd.depth != 2 * size - 2 - m1)
				|| (!use && cd.corner == 2 && cd.depth != size - 1 - m1)))
			|| (sticky && ((use && cd.corner == 0 && cd.depth == size - 1)
				|| (use && cd.corner == 1 && cd.depth > size - 1)
				|| (use && cd.corner == 2 && cd.depth < size - 1)
				|| (!use && cd.corner == 0 && cd.depth != size - 1)
				|| (!use && cd.corner == 1 && cd.depth <= size - 1)
				|| (!use && cd.corner == 2 && cd.depth >= size - 1)))) {
			glPushMatrix();
			glTranslate(0, s2 * FACET_LENGTH, -s0 * FACET_LENGTH);
			drawOctaFacet(w, d, -1, -1, c, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 0 && cd.depth == size - 1)
				|| (use && cd.corner == 1 && cd.depth == m1)
				|| (use && cd.corner == 2 && cd.depth == size)
				|| (!use && cd.corner == 0 && cd.depth != size - 1)
				|| (!use && cd.corner == 1 && cd.depth != m1)
				|| (!use && cd.corner == 2 && cd.depth != size)))
			|| (sticky && ((use && cd.corner == 0 && cd.depth == size - 1)
				|| (use && cd.corner == 1 && cd.depth < size - 1)
				|| (use && cd.corner == 2 && cd.depth > size - 1)
				|| (!use && cd.corner == 0 && cd.depth != size - 1)
				|| (!use && cd.corner == 1 && cd.depth >= size - 1)
				|| (!use && cd.corner == 2 && cd.depth <= size - 1)))) {
			glPushMatrix();
			glTranslate(0, -s2 * FACET_LENGTH, s0 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, -1, -1, c, d, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 1 && cd.depth == size - 1)
				|| (use && cd.corner == 0 && cd.depth == m1)
				|| (use && cd.corner == 2 && cd.depth == size)
				|| (!use && cd.corner == 1 && cd.depth != size - 1)
				|| (!use && cd.corner == 0 && cd.depth != m1)
				|| (!use && cd.corner == 2 && cd.depth != size)))
			|| (sticky && ((use && cd.corner == 1 && cd.depth == size - 1)
				|| (use && cd.corner == 0 && cd.depth < size - 1)
				|| (use && cd.corner == 2 && cd.depth > size - 1)
				|| (!use && cd.corner == 1 && cd.depth != size - 1)
				|| (!use && cd.corner == 0 && cd.depth >= size - 1)
				|| (!use && cd.corner == 2 && cd.depth <= size - 1)))) {
			glPushMatrix();
			glTranslate(s0 * FACET_LENGTH, -s2 * FACET_LENGTH, 0);
			drawOctaFacet(w, -1, -1, -1, -1, -1, c, d, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 0 && cd.depth == size - 1)
				|| (use && cd.corner == 1 && cd.depth == 2 * size - 2 - m1)
				|| (use && cd.corner == 2 && cd.depth == size)
				|| (!use && cd.corner == 0 && cd.depth != size - 1)
				|| (!use && cd.corner == 1 && cd.depth != 2 * size - 2 - m1)
				|| (!use && cd.corner == 2 && cd.depth != size)))
			|| (sticky && ((use && cd.corner == 0 && cd.depth == size - 1)
				|| (use && cd.corner != 0 && cd.depth > size - 1)
				|| (!use && cd.corner == 0 && cd.depth != size - 1)
				|| (!use && cd.corner != 0 && cd.depth <= size - 1)))) {
			glPushMatrix();
			glTranslate(0, -s2 * FACET_LENGTH, -s0 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, -1, -1, -1, -1, c, d);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 1 && cd.depth == size - 1)
				|| (use && cd.corner == 0 && cd.depth == 2 * size - 2 - m1)
				|| (use && cd.corner == 2 && cd.depth == size)
				|| (!use && cd.corner == 1 && cd.depth != size - 1)
				|| (!use && cd.corner == 0 && cd.depth != 2 * size - 2 - m1)
				|| (!use && cd.corner == 2 && cd.depth != size)))
			|| (sticky && ((use && cd.corner == 1 && cd.depth == size - 1)
				|| (use && cd.corner != 1 && cd.depth > size - 1)
				|| (!use && cd.corner == 1 && cd.depth != size - 1)
				|| (!use && cd.corner != 1 && cd.depth <= size - 1)))) {
			glPushMatrix();
			glTranslate(-s0 * FACET_LENGTH, -s2 * FACET_LENGTH, 0);
			drawOctaFacet(w, -1, -1, -1, -1, d, -1, -1, c);
			glPopMatrix();
		}

		if (all || (!sticky && ((use && cd.corner == 2 && cd.depth == size - 1)
				|| (use && cd.corner == 1 && cd.depth == size)
				|| (use && cd.corner == 0 && cd.depth == m1)
				|| (!use && cd.corner == 2 && cd.depth != size - 1)
				|| (!use && cd.corner == 1 && cd.depth != size)
				|| (!use && cd.corner == 0 && cd.depth != m1)))
			|| (sticky && ((use && cd.corner == 2 && cd.depth == size - 1)
				|| (use && cd.corner == 1 && cd.depth > size - 1)
				|| (use && cd.corner == 0 && cd.depth < size - 1)
				|| (!use && cd.corner == 2 && cd.depth != size - 1)
				|| (!use && cd.corner == 1 && cd.depth <= size - 1)
				|| (!use && cd.corner == 0 && cd.depth >= size - 1)))) {
			glPushMatrix();
			glTranslate(s0 * FACET_LENGTH, 0, -s2 * FACET_LENGTH);
			drawOctaFacet(w, e, -1, -1, -1, -1, -1, f, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 2 && cd.depth == size - 1)
				|| (use && cd.corner == 0 && cd.depth == size - 1 - m1)
				|| (use && cd.corner == 1 && cd.depth == m1)
				|| (!use && cd.corner == 2 && cd.depth != size - 1)
				|| (!use && cd.corner == 0 && cd.depth != size - 1 - m1)
				|| (!use && cd.corner == 1 && cd.depth != m1)))
			|| (sticky && ((use && cd.corner == 2 && cd.depth == size - 1)
				|| (use && cd.corner != 2 && cd.depth < size - 1)
				|| (!use && cd.corner == 2 && cd.depth != size - 1)
				|| (!use && cd.corner != 2 && cd.depth >= size - 1)))) {
			glPushMatrix();
			glTranslate(s2 * FACET_LENGTH, 0, s0 * FACET_LENGTH);
			drawOctaFacet(w, -1, e, -1, -1, -1, f, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 2 && cd.depth == size - 1)
				|| (use && cd.corner == 1 && cd.depth == size - 1 - m1)
				|| (use && cd.corner == 0 && cd.depth == 2 * size - 2 - m1)
				|| (!use && cd.corner == 2 && cd.depth != size - 1)
				|| (!use && cd.corner == 1 && cd.depth != size - 1 - m1)
				|| (!use && cd.corner == 0 && cd.depth != 2 * size - 2 - m1)))
			|| (sticky && ((use && cd.corner == 2 && cd.depth == size - 1)
				|| (use && cd.corner == 1 && cd.depth < size - 1)
				|| (use && cd.corner == 0 && cd.depth > size - 1)
				|| (!use && cd.corner == 2 && cd.depth != size - 1)
				|| (!use && cd.corner == 1 && cd.depth >= size - 1)
				|| (!use && cd.corner == 0 && cd.depth <= size - 1)))) {
			glPushMatrix();
			glTranslate(-s0 * FACET_LENGTH, 0, s2 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, e, -1, f, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 2 && cd.depth == size - 1)
				|| (use && cd.corner == 0 && cd.depth == size)
				|| (use && cd.corner == 1 && cd.depth == 2 * size - 2 - m1)
				|| (!use && cd.corner == 2 && cd.depth != size - 1)
				|| (!use && cd.corner == 0 && cd.depth != size)
				|| (!use && cd.corner == 1 && cd.depth != 2 * size - 2 - m1)))
			|| (sticky && ((use && cd.corner == 2 && cd.depth == size - 1)
				|| (use && cd.corner != 2 && cd.depth > size - 1)
				|| (!use && cd.corner == 2 && cd.depth != size - 1)
				|| (!use && cd.corner != 2 && cd.depth <= size - 1)))) {
			glPushMatrix();
			glTranslate(-s2 * FACET_LENGTH, 0, -s0 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, -1, e, -1, -1, -1, f);
			glPopMatrix();
		}

		if (all || (!sticky && ((use && cd.corner == 2 && cd.depth == size - 1)
				|| (use && cd.corner == 0 && cd.depth == size)
				|| (use && cd.corner == 1 && cd.depth == m1)
				|| (!use && cd.corner == 2 && cd.depth != size - 1)
				|| (!use && cd.corner == 0 && cd.depth != size)
				|| (!use && cd.corner == 1 && cd.depth != m1)))
			|| (sticky && ((use && cd.corner == 2 && cd.depth == size - 1)
				|| (use && cd.corner == 0 && cd.depth > size - 1)
				|| (use && cd.corner == 1 && cd.depth < size - 1)
				|| (!use && cd.corner == 2 && cd.depth != size - 1)
				|| (!use && cd.corner == 0 && cd.depth <= size - 1)
				|| (!use && cd.corner == 1 && cd.depth >= size - 1)))) {
			glPushMatrix();
			glTranslate(-s2 * FACET_LENGTH, 0, s0 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, f, -1, e, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 2 && cd.depth == size - 1)
				|| (use && cd.corner == 1 && cd.depth == size - 1 - m1)
				|| (use && cd.corner == 0 && cd.depth == m1)
				|| (!use && cd.corner == 2 && cd.depth != size - 1)
				|| (!use && cd.corner == 1 && cd.depth != size - 1 - m1)
				|| (!use && cd.corner == 0 && cd.depth != m1)))
			|| (sticky && ((use && cd.corner == 2 && cd.depth == size - 1)
				|| (use && cd.corner != 2 && cd.depth < size - 1)
				|| (!use && cd.corner == 2 && cd.depth != size - 1)
				|| (!use && cd.corner != 2 && cd.depth >= size - 1)))) {
			glPushMatrix();
			glTranslate(s0 * FACET_LENGTH, 0, s2 * FACET_LENGTH);
			drawOctaFacet(w, -1, f, -1, -1, -1, e, -1, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 2 && cd.depth == size - 1)
				|| (use && cd.corner == 0 && cd.depth == size - 1 - m1)
				|| (use && cd.corner == 1 && cd.depth == 2 * size - 2 - m1)
				|| (!use && cd.corner == 2 && cd.depth != size - 1)
				|| (!use && cd.corner == 0 && cd.depth != size - 1 - m1)
				|| (!use && cd.corner == 1 && cd.depth != 2 * size - 2 - m1)))
			|| (sticky && ((use && cd.corner == 2 && cd.depth == size - 1)
				|| (use && cd.corner == 0 && cd.depth < size - 1)
				|| (use && cd.corner == 1 && cd.depth > size - 1)
				|| (!use && cd.corner == 2 && cd.depth != size - 1)
				|| (!use && cd.corner == 0 && cd.depth >= size - 1)
				|| (!use && cd.corner == 1 && cd.depth <= size - 1)))) {
			glPushMatrix();
			glTranslate(s2 * FACET_LENGTH, 0, -s0 * FACET_LENGTH);
			drawOctaFacet(w, f, -1, -1, -1, -1, -1, e, -1);
			glPopMatrix();
		}
		if (all || (!sticky && ((use && cd.corner == 2 && cd.depth == size - 1)
				|| (use && cd.corner == 1 && cd.depth == size)
				|| (use && cd.corner == 0 && cd.depth == 2 * size - 2 - m1)
				|| (!use && cd.corner == 2 && cd.depth != size - 1)
				|| (!use && cd.corner == 1 && cd.depth != size)
				|| (!use && cd.corner == 0 && cd.depth != 2 * size - 2 - m1)))
			|| (sticky && ((use && cd.corner == 2 && cd.depth == size - 1)
				|| (use && cd.corner != 2 && cd.depth > size - 1)
				|| (!use && cd.corner == 2 && cd.depth != size - 1)
				|| (!use && cd.corner != 2 && cd.depth <= size - 1)))) {
			glPushMatrix();
			glTranslate(-s0 * FACET_LENGTH, 0, -s2 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, -1, f, -1, -1, -1, f);
			glPopMatrix();
		}
	}
	if (size > 4) { /* EDGE 2 */
		int s3, m1, m2;
		int s4 = size - 1;
		int a, b, c, d, e, f;
		s1 = 1;
		s2 = 2 * size - 5;
		s3 = 3;
		a = 5;
		b = 7;
		c = (size - 2) * (size - 2) + 1;
		d = s4 * s4 - 2;
		e = s4 * s4 + 3;
		f = size * size - 4;
		m1 = 1;
		m2 = 2;
		if (all || (use && cd.corner == 1 && cd.depth == size - 1)
				|| (use && cd.corner == 0 && cd.depth == size - 1 - m1)
				|| (use && cd.corner == 2 && cd.depth == m2)
				|| (!use && cd.corner == 1 && cd.depth != size - 1)
				|| (!use && cd.corner == 0 && cd.depth != size - 1 - m1)
				|| (!use && cd.corner == 2 && cd.depth != m2)) {
			glPushMatrix();
			glTranslate(s3 * FACET_LENGTH, s2 * FACET_LENGTH, -s1 * FACET_LENGTH);
			drawTetraFacet(w, a, -1, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
			glPushMatrix();
			glTranslate(s3 * FACET_LENGTH, s2 * FACET_LENGTH, s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, b, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && cd.corner == 0 && cd.depth == size - 1)
				|| (use && cd.corner == 1 && cd.depth == size - 1 - m1)
				|| (use && cd.corner == 2 && cd.depth == m2)
				|| (!use && cd.corner == 0 && cd.depth != size - 1)
				|| (!use && cd.corner == 1 && cd.depth != size - 1 - m1)
				|| (!use && cd.corner == 2 && cd.depth != m2)) {
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, s2 * FACET_LENGTH, s3 * FACET_LENGTH);
			drawTetraFacet(w, -1, a, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, s2 * FACET_LENGTH, s3 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, b, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && cd.corner == 1 && cd.depth == size - 1)
				|| (use && cd.corner == 0 && cd.depth == size)
				|| (use && cd.corner == 2 && cd.depth == m2)
				|| (!use && cd.corner == 1 && cd.depth != size - 1)
				|| (!use && cd.corner == 0 && cd.depth != size)
				|| (!use && cd.corner == 2 && cd.depth != m2)) {
			glPushMatrix();
			glTranslate(-s3 * FACET_LENGTH, s2 * FACET_LENGTH, s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, a, -1, -1, -1, -1, -1);
			glPopMatrix();
			glPushMatrix();
			glTranslate(-s3 * FACET_LENGTH, s2 * FACET_LENGTH, -s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, b, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && cd.corner == 0 && cd.depth == size - 1)
				|| (use && cd.corner == 1 && cd.depth == size)
				|| (use && cd.corner == 2 && cd.depth == m2)
				|| (!use && cd.corner == 0 && cd.depth != size - 1)
				|| (!use && cd.corner == 1 && cd.depth != size)
				|| (!use && cd.corner == 2 && cd.depth != m2)) {
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, s2 * FACET_LENGTH, -s3 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, a, -1, -1, -1, -1);
			glPopMatrix();
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, s2 * FACET_LENGTH, -s3 * FACET_LENGTH);
			drawTetraFacet(w, b, -1, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}

		if (all || (use && cd.corner == 0 && cd.depth == size - 1)
				|| (use && cd.corner == 1 && cd.depth == size - 1 - m1)
				|| (use && cd.corner == 2 && cd.depth == 2 * size - 2 - m2)
				|| (!use && cd.corner == 0 && cd.depth != size - 1)
				|| (!use && cd.corner == 1 && cd.depth != size - 1 - m1)
				|| (!use && cd.corner == 2 && cd.depth != 2 * size - 2 - m2)) {
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, -s2 * FACET_LENGTH, s3 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, a, -1, -1, -1);
			glPopMatrix();
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, -s2 * FACET_LENGTH, s3 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, b, -1, -1);
			glPopMatrix();
		}
		if (all || (use && cd.corner == 1 && cd.depth == size - 1)
				|| (use && cd.corner == 0 && cd.depth == size - 1 - m1)
				|| (use && cd.corner == 2 && cd.depth == 2 * size - 2 - m2)
				|| (!use && cd.corner == 1 && cd.depth != size - 1)
				|| (!use && cd.corner == 0 && cd.depth != size - 1 - m1)
				|| (!use && cd.corner == 2 && cd.depth != 2 * size - 2 - m2)) {
			glPushMatrix();
			glTranslate(s3 * FACET_LENGTH, -s2 * FACET_LENGTH, s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, a, -1, -1);
			glPopMatrix();
			glPushMatrix();
			glTranslate(s3 * FACET_LENGTH, -s2 * FACET_LENGTH, -s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, -1, b, -1);
			glPopMatrix();
		}
		if (all || (use && cd.corner == 0 && cd.depth == size - 1)
				|| (use && cd.corner == 1 && cd.depth == size)
				|| (use && cd.corner == 2 && cd.depth == 2 * size - 2 - m2)
				|| (!use && cd.corner == 0 && cd.depth != size - 1)
				|| (!use && cd.corner == 1 && cd.depth != size)
				|| (!use && cd.corner == 2 && cd.depth != 2 * size - 2 - m2)) {
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, -s2 * FACET_LENGTH, -s3 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, -1, a, -1);
			glPopMatrix();
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, -s2 * FACET_LENGTH, -s3 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, -1, -1, b);
			glPopMatrix();
		}
		if (all || (use && cd.corner == 1 && cd.depth == size - 1)
				|| (use && cd.corner == 0 && cd.depth == size)
				|| (use && cd.corner == 2 && cd.depth == 2 * size - 2 - m2)
				|| (!use && cd.corner == 1 && cd.depth != size - 1)
				|| (!use && cd.corner == 0 && cd.depth != size)
				|| (!use && cd.corner == 2 && cd.depth != 2 * size - 2 - m2)) {
			glPushMatrix();
			glTranslate(-s3 * FACET_LENGTH, -s2 * FACET_LENGTH, -s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, -1, -1, a);
			glPopMatrix();
			glPushMatrix();
			glTranslate(-s3 * FACET_LENGTH, -s2 * FACET_LENGTH, s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, b, -1, -1, -1);
			glPopMatrix();
		}

		if (all || (use && cd.corner == 1 && cd.depth == size - 1)
				|| (use && cd.corner == 0 && cd.depth == m2)
				|| (use && cd.corner == 2 && cd.depth == size - 1 - m1)
				|| (!use && cd.corner == 1 && cd.depth != size - 1)
				|| (!use && cd.corner == 0 && cd.depth != m2)
				|| (!use && cd.corner == 2 && cd.depth != size - 1 - m1)) {
			glPushMatrix();
			glTranslate(s2 * FACET_LENGTH, s3 * FACET_LENGTH, -s1 * FACET_LENGTH);
			drawTetraFacet(w, c, -1, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
			glPushMatrix();
			glTranslate(s2 * FACET_LENGTH, s3 * FACET_LENGTH, s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, d, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && cd.corner == 0 && cd.depth == size - 1)
				|| (use && cd.corner == 1 && cd.depth == m2)
				|| (use && cd.corner == 2 && cd.depth == size - 1 - m1)
				|| (!use && cd.corner == 0 && cd.depth != size - 1)
				|| (!use && cd.corner == 1 && cd.depth != m2)
				|| (!use && cd.corner == 2 && cd.depth != size - 1 - m1)) {
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, s3 * FACET_LENGTH, s2 * FACET_LENGTH);
			drawTetraFacet(w, -1, c, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, s3 * FACET_LENGTH, s2 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, d, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && cd.corner == 1 && cd.depth == size - 1)
				|| (use && cd.corner == 0 && cd.depth == 2 * size - 2 - m2)
				|| (use && cd.corner == 2 && cd.depth == size - 1 - m1)
				|| (!use && cd.corner == 1 && cd.depth != size - 1)
				|| (!use && cd.corner == 0 && cd.depth != 2 * size - 2 - m2)
				|| (!use && cd.corner == 2 && cd.depth != size - 1 - m1)) {
			glPushMatrix();
			glTranslate(-s2 * FACET_LENGTH, s3 * FACET_LENGTH, s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, c, -1, -1, -1, -1, -1);
			glPopMatrix();
			glPushMatrix();
			glTranslate(-s2 * FACET_LENGTH, s3 * FACET_LENGTH, -s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, d, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && cd.corner == 0 && cd.depth == size - 1)
				|| (use && cd.corner == 1 && cd.depth == 2 * size - 2 - m2)
				|| (use && cd.corner == 2 && cd.depth == size - 1 - m1)
				|| (!use && cd.corner == 0 && cd.depth != size - 1)
				|| (!use && cd.corner == 1 && cd.depth != 2 * size - 2 - m2)
				|| (!use && cd.corner == 2 && cd.depth != size - 1 - m1)) {
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, s3 * FACET_LENGTH, -s2 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, c, -1, -1, -1, -1);
			glPopMatrix();
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, s3 * FACET_LENGTH, -s2 * FACET_LENGTH);
			drawTetraFacet(w, d, -1, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && cd.corner == 0 && cd.depth == size - 1)
				|| (use && cd.corner == 1 && cd.depth == m2)
				|| (use && cd.corner == 2 && cd.depth == size)
				|| (!use && cd.corner == 0 && cd.depth != size - 1)
				|| (!use && cd.corner == 1 && cd.depth != m2)
				|| (!use && cd.corner == 2 && cd.depth != size)) {
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, -s3 * FACET_LENGTH, s2 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, c, -1, -1, -1);
			glPopMatrix();
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, -s3 * FACET_LENGTH, s2 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, d, -1, -1);
			glPopMatrix();
		}
		if (all || (use && cd.corner == 1 && cd.depth == size - 1)
				|| (use && cd.corner == 0 && cd.depth == m2)
				|| (use && cd.corner == 2 && cd.depth == size)
				|| (!use && cd.corner == 1 && cd.depth != size - 1)
				|| (!use && cd.corner == 0 && cd.depth != m2)
				|| (!use && cd.corner == 2 && cd.depth != size)) {
			glPushMatrix();
			glTranslate(s2 * FACET_LENGTH, -s3 * FACET_LENGTH, s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, c, -1, -1);
			glPopMatrix();
			glPushMatrix();
			glTranslate(s2 * FACET_LENGTH, -s3 * FACET_LENGTH, -s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, -1, d, -1);
			glPopMatrix();
		}
		if (all || (use && cd.corner == 0 && cd.depth == size - 1)
				|| (use && cd.corner == 1 && cd.depth == 2 * size - 2 - m2)
				|| (use && cd.corner == 2 && cd.depth == size)
				|| (!use && cd.corner == 0 && cd.depth != size - 1)
				|| (!use && cd.corner == 1 && cd.depth != 2 * size - 2 - m2)
				|| (!use && cd.corner == 2 && cd.depth != size)) {
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, -s3 * FACET_LENGTH, -s2 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, -1, c, -1);
			glPopMatrix();
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, -s3 * FACET_LENGTH, -s2 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, -1, -1, d);
			glPopMatrix();
		}
		if (all || (use && cd.corner == 1 && cd.depth == size - 1)
				|| (use && cd.corner == 0 && cd.depth == 2 * size - 2 - m2)
				|| (use && cd.corner == 2 && cd.depth == size)
				|| (!use && cd.corner == 1 && cd.depth != size - 1)
				|| (!use && cd.corner == 0 && cd.depth != 2 * size - 2 - m2)
				|| (!use && cd.corner == 2 && cd.depth != size)) {
			glPushMatrix();
			glTranslate(-s2 * FACET_LENGTH, -s3 * FACET_LENGTH, -s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, -1, -1, c);
			glPopMatrix();
			glPushMatrix();
			glTranslate(-s2 * FACET_LENGTH, -s3 * FACET_LENGTH, s1 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, d, -1, -1, -1);
			glPopMatrix();
		}

		if (all || (use && cd.corner == 2 && cd.depth == size - 1)
				|| (use && cd.corner == 1 && cd.depth == size)
				|| (use && cd.corner == 0 && cd.depth == m2)
				|| (!use && cd.corner == 2 && cd.depth != size - 1)
				|| (!use && cd.corner == 1 && cd.depth != size)
				|| (!use && cd.corner == 0 && cd.depth != m2)) {
			glPushMatrix();
			glTranslate(s2 * FACET_LENGTH, s1 * FACET_LENGTH, -s3 * FACET_LENGTH);
			drawTetraFacet(w, e, -1, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
			glPushMatrix();
			glTranslate(s2 * FACET_LENGTH, -s1 * FACET_LENGTH, -s3 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, -1, f, -1);
			glPopMatrix();
		}
		if (all || (use && cd.corner == 2 && cd.depth == size - 1)
				|| (use && cd.corner == 0 && cd.depth == size - 1 - m1)
				|| (use && cd.corner == 1 && cd.depth == m2)
				|| (!use && cd.corner == 2 && cd.depth != size - 1)
				|| (!use && cd.corner == 0 && cd.depth != size - 1 - m1)
				|| (!use && cd.corner == 1 && cd.depth != m2)) {
			glPushMatrix();
			glTranslate(s3 * FACET_LENGTH, s1 * FACET_LENGTH, s2 * FACET_LENGTH);
			drawTetraFacet(w, -1, e, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
			glPushMatrix();
			glTranslate(s3 * FACET_LENGTH, -s1 * FACET_LENGTH, s2 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, f, -1, -1);
			glPopMatrix();
		}
		if (all || (use && cd.corner == 2 && cd.depth == size - 1)
				|| (use && cd.corner == 1 && cd.depth == size - 1 - m1)
				|| (use && cd.corner == 0 && cd.depth == 2 * size - 2 - m2)
				|| (!use && cd.corner == 2 && cd.depth != size - 1)
				|| (!use && cd.corner == 1 && cd.depth != size - 1 - m1)
				|| (!use && cd.corner == 0 && cd.depth != 2 * size - 2 - m2)) {
			glPushMatrix();
			glTranslate(-s2 * FACET_LENGTH, s1 * FACET_LENGTH, s3 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, e, -1, -1, -1, -1, -1);
			glPopMatrix();
			glPushMatrix();
			glTranslate(-s2 * FACET_LENGTH, -s1 * FACET_LENGTH, s3 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, f, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && cd.corner == 2 && cd.depth == size - 1)
				|| (use && cd.corner == 0 && cd.depth == size)
				|| (use && cd.corner == 1 && cd.depth == 2 * size - 2 - m2)
				|| (!use && cd.corner == 2 && cd.depth != size - 1)
				|| (!use && cd.corner == 0 && cd.depth != size)
				|| (!use && cd.corner == 1 && cd.depth != 2 * size - 2 - m2)) {
			glPushMatrix();
			glTranslate(-s3 * FACET_LENGTH, s1 * FACET_LENGTH, -s2 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, e, -1, -1, -1, -1);
			glPopMatrix();
			glPushMatrix();
			glTranslate(-s3 * FACET_LENGTH, -s1 * FACET_LENGTH, -s2 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, -1, -1, f);
			glPopMatrix();
		}
		if (all || (use && cd.corner == 2 && cd.depth == size - 1)
				|| (use && cd.corner == 0 && cd.depth == size)
				|| (use && cd.corner == 1 && cd.depth == m2)
				|| (!use && cd.corner == 2 && cd.depth != size - 1)
				|| (!use && cd.corner == 0 && cd.depth != size)
				|| (!use && cd.corner == 1 && cd.depth != m2)) {
			glPushMatrix();
			glTranslate(-s3 * FACET_LENGTH, -s1 * FACET_LENGTH, s2 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, e, -1, -1, -1);
			glPopMatrix();
			glPushMatrix();
			glTranslate(-s3 * FACET_LENGTH, s1 * FACET_LENGTH, s2 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, f, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && cd.corner == 2 && cd.depth == size - 1)
				|| (use && cd.corner == 1 && cd.depth == size - 1 - m1)
				|| (use && cd.corner == 0 && cd.depth == m2)
				|| (!use && cd.corner == 2 && cd.depth != size - 1)
				|| (!use && cd.corner == 1 && cd.depth != size - 1 - m1)
				|| (!use && cd.corner == 0 && cd.depth != m2)) {
			glPushMatrix();
			glTranslate(s2 * FACET_LENGTH, -s1 * FACET_LENGTH, s3 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, e, -1, -1);
			glPopMatrix();
			glPushMatrix();
			glTranslate(s2 * FACET_LENGTH, s1 * FACET_LENGTH, s3 * FACET_LENGTH);
			drawTetraFacet(w, -1, f, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && cd.corner == 2 && cd.depth == size - 1)
				|| (use && cd.corner == 0 && cd.depth == size - 1 - m1)
				|| (use && cd.corner == 1 && cd.depth == 2 * size - 2 - m2)
				|| (!use && cd.corner == 2 && cd.depth != size - 1)
				|| (!use && cd.corner == 0 && cd.depth != size - 1 - m1)
				|| (!use && cd.corner == 1 && cd.depth != 2 * size - 2 - m2)) {
			glPushMatrix();
			glTranslate(s3 * FACET_LENGTH, -s1 * FACET_LENGTH, -s2 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, -1, e, -1);
			glPopMatrix();
			glPushMatrix();
			glTranslate(s3 * FACET_LENGTH, s1 * FACET_LENGTH, -s2 * FACET_LENGTH);
			drawTetraFacet(w, f, -1, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && cd.corner == 2 && cd.depth == size - 1)
				|| (use && cd.corner == 1 && cd.depth == size)
				|| (use && cd.corner == 0 && cd.depth == 2 * size - 2 - m2)
				|| (!use && cd.corner == 2 && cd.depth != size - 1)
				|| (!use && cd.corner == 1 && cd.depth != size)
				|| (!use && cd.corner == 0 && cd.depth != 2 * size - 2 - m2)) {
			glPushMatrix();
			glTranslate(-s2 * FACET_LENGTH, -s1 * FACET_LENGTH, -s3 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, -1, -1, -1, -1, e);
			glPopMatrix();
			glPushMatrix();
			glTranslate(-s2 * FACET_LENGTH, s1 * FACET_LENGTH, -s3 * FACET_LENGTH);
			drawTetraFacet(w, -1, -1, -1, f, -1, -1, -1, -1);
			glPopMatrix();
		}
		/* FACE 2 */
		s1 = 2;
		s2 = 2 * size - 6;
		s3 = size - 2;
		a = 6;
		b = s3 * s3 + 2; /* 11, 18, 27 */
		c = s3 * s3 + 2 * s3 - 2; /* 13, 22, 33 */
		m1 = 1;
		m2 = 2;
		if (all || (use && cd.corner == 2 && cd.depth == m2)
				|| (use && cd.corner == 0 && cd.depth == size - 1 - m1)
				|| (use && cd.corner == 1 && cd.depth == size)
				|| (!use && cd.corner == 2 && cd.depth != m2)
				|| (!use && cd.corner == 0 && cd.depth != size - 1 - m1)
				|| (!use && cd.corner == 1 && cd.depth != size)) {
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, s2 * FACET_LENGTH, -s1 * FACET_LENGTH);
			drawOctaFacet(w, a, -1, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && cd.corner == 0 && cd.depth == m2)
				|| (use && cd.corner == 2 && cd.depth == size - 1 - m1)
				|| (use && cd.corner == 1 && cd.depth == size)
				|| (!use && cd.corner == 0 && cd.depth != m2)
				|| (!use && cd.corner == 2 && cd.depth != size - 1 - m1)
				|| (!use && cd.corner == 1 && cd.depth != size)) {
			glPushMatrix();
			glTranslate(s2 * FACET_LENGTH, s1 * FACET_LENGTH, -s1 * FACET_LENGTH);
			drawOctaFacet(w, b, -1, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && cd.corner == 1 && cd.depth == 2 * size - 2 - m2)
				|| (use && cd.corner != 1 && cd.depth == size - 1 - m1)
				|| (!use && cd.corner == 1 && cd.depth != 2 * size - 2 - m2)
				|| (!use && cd.corner != 1 && cd.depth != size - 1 - m1)) {
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, s1 * FACET_LENGTH, -s2 * FACET_LENGTH);
			drawOctaFacet(w, c, -1, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && cd.corner == 2 && cd.depth == m2)
				|| (use && cd.corner != 2 && cd.depth == size - 1 - m1)
				|| (!use && cd.corner == 2 && cd.depth != m2)
				|| (!use && cd.corner != 2 && cd.depth != size - 1 - m1)) {
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, s2 * FACET_LENGTH, s1 * FACET_LENGTH);
			drawOctaFacet(w, -1, a, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && cd.corner == 1 && cd.depth == m2)
				|| (use && cd.corner != 1 && cd.depth == size - 1 - m1)
				|| (!use && cd.corner == 1 && cd.depth != m2)
				|| (!use && cd.corner != 1 && cd.depth != size - 1 - m1)) {
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, s1 * FACET_LENGTH, s2 * FACET_LENGTH);
			drawOctaFacet(w, -1, b, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && cd.corner == 0 && cd.depth == m2)
				|| (use && cd.corner != 0 && cd.depth == size - 1 - m1)
				|| (!use && cd.corner == 0 && cd.depth != m2)
				|| (!use && cd.corner != 0 && cd.depth != size - 1 - m1)) {
			glPushMatrix();
			glTranslate(s2 * FACET_LENGTH, s1 * FACET_LENGTH, s1 * FACET_LENGTH);
			drawOctaFacet(w, -1, c, -1, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && cd.corner == 2 && cd.depth == m2)
				|| (use && cd.corner == 0 && cd.depth == size)
				|| (use && cd.corner == 1 && cd.depth == size - 1 - m1)
				|| (!use && cd.corner == 2 && cd.depth != m2)
				|| (!use && cd.corner == 0 && cd.depth != size)
				|| (!use && cd.corner == 1 && cd.depth != size - 1 - m1)) {
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, s2 * FACET_LENGTH, s1 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, a, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && cd.corner == 0 && cd.depth == 2 * size - 2 - m2)
				|| (use && cd.corner != 0 && cd.depth == size - 1 - m1)
				|| (!use && cd.corner == 0 && cd.depth != 2 * size - 2 - m2)
				|| (!use && cd.corner != 0 && cd.depth != size - 1 - m1)) {
			glPushMatrix();
			glTranslate(-s2 * FACET_LENGTH, s1 * FACET_LENGTH, s1 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, b, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && cd.corner == 2 && cd.depth == size - 1 - m1)
				|| (use && cd.corner == 0 && cd.depth == size)
				|| (use && cd.corner == 1 && cd.depth == m2)
				|| (!use && cd.corner == 2 && cd.depth != size - 1 - m1)
				|| (!use && cd.corner == 0 && cd.depth != size)
				|| (!use && cd.corner == 1 && cd.depth != m2)) {
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, s1 * FACET_LENGTH, s2 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, c, -1, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && cd.corner == 2 && cd.depth == m2)
				|| (use && cd.corner != 2 && cd.depth == size)
				|| (!use && cd.corner == 2 && cd.depth != m2)
				|| (!use && cd.corner != 2 && cd.depth != size)) {
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, s2 * FACET_LENGTH, -s1 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, -1, a, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && cd.corner == 1 && cd.depth == 2 * size - 2 - m2)
				|| (use && cd.corner == 0 && cd.depth == size)
				|| (use && cd.corner == 2 && cd.depth == size - 1 - m1)
				|| (!use && cd.corner == 1 && cd.depth != 2 * size - 2 - m2)
				|| (!use && cd.corner == 0 && cd.depth != size)
				|| (!use && cd.corner == 2 && cd.depth != size - 1 - m1)) {
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, s1 * FACET_LENGTH, -s2 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, -1, b, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && cd.corner == 0 && cd.depth == 2 * size - 2 - m2)
				|| (use && cd.corner == 1 && cd.depth == size)
				|| (use && cd.corner == 2 && cd.depth == size - 1 - m1)
				|| (!use && cd.corner == 0 && cd.depth != 2 * size - 2 - m2)
				|| (!use && cd.corner == 1 && cd.depth != size)
				|| (!use && cd.corner == 2 && cd.depth != size - 1 - m1)) {
			glPushMatrix();
			glTranslate(-s2 * FACET_LENGTH, s1 * FACET_LENGTH, -s1 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, -1, c, -1, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && cd.corner == 2 && cd.depth == 2 * size - 2 - m2)
				|| (use && cd.corner == 1 && cd.depth == size - 1 - m1)
				|| (use && cd.corner == 0 && cd.depth == size)
				|| (!use && cd.corner == 2 && cd.depth != 2 * size - 2 - m2)
				|| (!use && cd.corner == 1 && cd.depth != size - 1 - m1)
				|| (!use && cd.corner == 0 && cd.depth != size)) {
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, -s2 * FACET_LENGTH, s1 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, -1, -1, a, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && cd.corner == 1 && cd.depth == m2)
				|| (use && cd.corner != 1 && cd.depth == size)
				|| (!use && cd.corner == 1 && cd.depth != m2)
				|| (!use && cd.corner != 1 && cd.depth != size)) {
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, -s1 * FACET_LENGTH, s2 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, -1, -1, b, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && cd.corner == 0 && cd.depth == 2 * size - 2 - m2)
				|| (use && cd.corner == 1 && cd.depth == size - 1 - m1)
				|| (use && cd.corner == 2 && cd.depth == size)
				|| (!use && cd.corner == 0 && cd.depth != 2 * size - 2 - m2)
				|| (!use && cd.corner == 1 && cd.depth != size - 1 - m1)
				|| (!use && cd.corner == 2 && cd.depth != size)) {
			glPushMatrix();
			glTranslate(-s2 * FACET_LENGTH, -s1 * FACET_LENGTH, s1 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, -1, -1, c, -1, -1, -1);
			glPopMatrix();
		}
		if (all || (use && cd.corner == 2 && cd.depth == 2 * size - 2 - m2)
				|| (use && cd.corner != 2 && cd.depth == size - 1 - m1)
				|| (!use && cd.corner == 2 && cd.depth != 2 * size - 2 - m2)
				|| (!use && cd.corner != 2 && cd.depth != size - 1 - m1)) {
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, -s2 * FACET_LENGTH, s1 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, -1, -1, -1, a, -1, -1);
			glPopMatrix();
		
		}
		if (all || (use && cd.corner == 0 && cd.depth == m2)
				|| (use && cd.corner == 1 && cd.depth == size - 1 - m1)
				|| (use && cd.corner == 2 && cd.depth == size)
				|| (!use && cd.corner == 0 && cd.depth != m2)
				|| (!use && cd.corner == 1 && cd.depth != size - 1 - m1)
				|| (!use && cd.corner == 2 && cd.depth != size)) {
			glPushMatrix();
			glTranslate(s2 * FACET_LENGTH, -s1 * FACET_LENGTH, s1 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, -1, -1, -1, b, -1, -1);
			glPopMatrix();
		}
		if (all || (use && cd.corner == 1 && cd.depth == m2)
				|| (use && cd.corner == 0 && cd.depth == size - 1 - m1)
				|| (use && cd.corner == 2 && cd.depth == size)
				|| (!use && cd.corner == 1 && cd.depth != m2)
				|| (!use && cd.corner == 0 && cd.depth != size - 1 - m1)
				|| (!use && cd.corner == 2 && cd.depth != size)) {
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, -s1 * FACET_LENGTH, s2 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, -1, -1, -1, c, -1, -1);
			glPopMatrix();
		}
		if (all || (use && cd.corner == 2 && cd.depth == 2 * size - 2 - m2)
				|| (use && cd.corner == 0 && cd.depth == size - 1 - m1)
				|| (use && cd.corner == 1 && cd.depth == size)
				|| (!use && cd.corner == 2 && cd.depth != 2 * size - 2 - m2)
				|| (!use && cd.corner == 0 && cd.depth != size - 1 - m1)
				|| (!use && cd.corner == 1 && cd.depth != size)) {
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, -s2 * FACET_LENGTH, -s1 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, -1, -1, -1, -1, a, -1);
			glPopMatrix();
		}
		if (all || (use && cd.corner == 0 && cd.depth == size - 1 - m1)
				|| (use && cd.corner == 1 && cd.depth == 2 * size - 2 - m2)
				|| (use && cd.corner == 2 && cd.depth == size)
				|| (!use && cd.corner == 0 && cd.depth != size - 1 - m1)
				|| (!use && cd.corner == 1 && cd.depth != 2 * size - 2 - m2)
				|| (!use && cd.corner == 2 && cd.depth != size)) {
			glPushMatrix();
			glTranslate(s1 * FACET_LENGTH, -s1 * FACET_LENGTH, -s2 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, -1, -1, -1, -1, b, -1);
			glPopMatrix();
		}
		if (all || (use && cd.corner == 0 && cd.depth == m2)
				|| (use && cd.corner != 0 && cd.depth == size)
				|| (!use && cd.corner == 0 && cd.depth != m2)
				|| (!use && cd.corner != 0 && cd.depth != size)) {
			glPushMatrix();
			glTranslate(s2 * FACET_LENGTH, -s1 * FACET_LENGTH, -s1 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, -1, -1, -1, -1, c, -1);
			glPopMatrix();
		}
		if (all || (use && cd.corner == 2 && cd.depth == 2 * size - 2 - m2)
				|| (use && cd.corner != 2 && cd.depth == size)
				|| (!use && cd.corner == 2 && cd.depth != 2 * size - 2 - m2)
				|| (!use && cd.corner != 2 && cd.depth != size)) {
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, -s2 * FACET_LENGTH, -s1 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, -1, -1, -1, -1, -1, a);
			glPopMatrix();
		}
		if (all || (use && cd.corner == 0 && cd.depth == 2 * size - 2 - m2)
				|| (use && cd.corner != 0 && cd.depth == size)
				|| (!use && cd.corner == 0 && cd.depth != 2 * size - 2 - m2)
				|| (!use && cd.corner != 0 && cd.depth != size)) {
			glPushMatrix();
			glTranslate(-s2 * FACET_LENGTH, -s1 * FACET_LENGTH, -s1 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, -1, -1, -1, -1, -1, b);
			glPopMatrix();
		}
		if (all || (use && cd.corner == 1 && cd.depth == 2 * size - 2 - m2)
				|| (use && cd.corner != 1 && cd.depth == size)
				|| (!use && cd.corner == 1 && cd.depth != 2 * size - 2 - m2)
				|| (!use && cd.corner != 1 && cd.depth != size)) {
			glPushMatrix();
			glTranslate(-s1 * FACET_LENGTH, -s1 * FACET_LENGTH, -s2 * FACET_LENGTH);
			drawOctaFacet(w, -1, -1, -1, -1, -1, -1, -1, c);
			glPopMatrix();
		}
	}
}

/*-
 * This rotates whole octahedron.
 */
static void
rotateAllFaces(OctGLWidget w)
{
	drawFaces(w, 0, 0, 1, False, True);
}

static void
rotateFaceSlice(OctGLWidget w, GLfloat rotateStep,
		GLfloat x, GLfloat y, GLfloat z,
		int face, int position, int direction)
{
	glPushMatrix();
	glRotatef(rotateStep, x, y, z);
	if (w->octGL.movement.control)
		drawFaces(w, face, 0, direction, False, True);
	else
		drawFaces(w, face, position, direction, True, False);
	glPopMatrix();
	if (!w->octGL.movement.control)
		drawFaces(w, face, position, direction, False, False);
}

/*-
 * This rotates whole octahedron.
 */
static void
rotateAllCorners(OctGLWidget w)
{
	drawCorners(w, 0, 0, 1, False, True);
}

static void
rotateCornerSlice(OctGLWidget w, GLfloat rotateStep,
		GLfloat x, GLfloat y, GLfloat z,
		int face, int position, int direction)
{
	glPushMatrix();
	glRotatef(rotateStep, x, y, z);
	if (w->octGL.movement.control)
		drawCorners(w, face, 0, direction, False, True);
	else
		drawCorners(w, face, position, direction, True, False);
	glPopMatrix();
	if (!w->octGL.movement.control)
		drawCorners(w, face, position, direction, False, False);
}

static void
drawOcta(OctGLWidget w)
{
	GLfloat rotateStep = 0.0;
	int face = w->octGL.movement.face;
	int position = w->octGL.movement.position;
	int direction = w->octGL.movement.direction;
	int style = w->octGL.movement.style;

	if (face == NO_FACE || direction == IGNORE_DIR) {
		if (style == PERIOD3)
			rotateAllFaces(w);
		else
			rotateAllCorners(w);
/* 8 face/corner rotate */
/*	  1-1-1  */
/*	111      */
/* 1 -1 -1 rotate front faces CCW <=> 0 LEFT */
/* -1 1 -1 rotate right face CCW <=> 0 BL */
/* -1 -1 1 rotate top face CCW <=> 1 TR */
/* 1 1 1 rotate left face CCW <=> 0 TOP */
/* -1 1 1 rotate front faces CW <=> 0 RIGHT */
/* 1 -1 1 rotate right face CW <=> 0 TR */
/* 1 1 -1 rotate top face CW <=> 1 BL */
/* -1 -1 -1 rotate left face CW <=> BOTTOM */
	} else if (style == PERIOD3) {
		rotateStep = (float) w->octGL.rotateStep;
		switch (face) {
		case 0:
			switch (direction) {
			case TR:
				rotateFaceSlice(w, rotateStep, -1, -1, -1, face, position, direction);
				break;
			case RIGHT:
				rotateFaceSlice(w, rotateStep, 1, -1, -1, face, position, direction);
				break;
			case BR:
				rotateFaceSlice(w, rotateStep, 1, -1, 1, face, position, direction);
				break;
			case BL:
				rotateFaceSlice(w, rotateStep, 1, 1, 1, face, position, direction);
				break;
			case LEFT:
				rotateFaceSlice(w, rotateStep, -1, 1, 1, face, position, direction);
				break;
			case TL:
				rotateFaceSlice(w, rotateStep, -1, 1, -1, face, position, direction);
				break;
			default:
				rotateAllFaces(w);
			}
			break;
		case 1:
			switch (direction) {
			case TOP:
				rotateFaceSlice(w, rotateStep, -1, 1, -1, face, position, direction);
				break;
			case TR:
				rotateFaceSlice(w, rotateStep, 1, 1, -1, face, position, direction);
				break;
			case BR:
				rotateFaceSlice(w, rotateStep, 1, -1, -1, face, position, direction);
				break;
			case BOTTOM:
				rotateFaceSlice(w, rotateStep, 1, -1, 1, face, position, direction);
				break;
			case BL:
				rotateFaceSlice(w, rotateStep, -1, -1, 1, face, position, direction);
				break;
			case TL:
				rotateFaceSlice(w, rotateStep, -1, 1, 1, face, position, direction);
				break;
			default:
				rotateAllFaces(w);
			}
			break;
		case 2:
			switch (direction) {
			case TR:
				rotateFaceSlice(w, rotateStep, -1, 1, -1, face, position, direction);
				break;
			case RIGHT:
				rotateFaceSlice(w, rotateStep, 1, 1, -1, face, position, direction);
				break;
			case BR:
				rotateFaceSlice(w, rotateStep, 1, 1, 1, face, position, direction);
				break;
			case BL:
				rotateFaceSlice(w, rotateStep, 1, -1, 1, face, position, direction);
				break;
			case LEFT:
				rotateFaceSlice(w, rotateStep, -1, -1, 1, face, position, direction);
				break;
			case TL:
				rotateFaceSlice(w, rotateStep, -1, -1, -1, face, position, direction);
				break;
			default:
				rotateAllFaces(w);
			}
			break;
		case 3:
			switch (direction) {
			case TOP:
				rotateFaceSlice(w, rotateStep, -1, -1, -1, face, position, direction);
				break;
			case TR:
				rotateFaceSlice(w, rotateStep, 1, -1, -1, face, position, direction);
				break;
			case BR:
				rotateFaceSlice(w, rotateStep, 1, 1, -1, face, position, direction);
				break;
			case BOTTOM:
				rotateFaceSlice(w, rotateStep, 1, 1, 1, face, position, direction);
				break;
			case BL:
				rotateFaceSlice(w, rotateStep, -1, 1, 1, face, position, direction);
				break;
			case TL:
				rotateFaceSlice(w, rotateStep, -1, -1, 1, face, position, direction);
				break;
			default:
				rotateAllFaces(w);
			}
			break;
		case 4:
			switch (direction) {
			case TR:
				rotateFaceSlice(w, rotateStep, -1, 1, -1, face, position, direction);
				break;
			case RIGHT:
				rotateFaceSlice(w, rotateStep, -1, 1, 1, face, position, direction);
				break;
			case BR:
				rotateFaceSlice(w, rotateStep, 1, 1, 1, face, position, direction);
				break;
			case BL:
				rotateFaceSlice(w, rotateStep, 1, -1, 1, face, position, direction);
				break;
			case LEFT:
				rotateFaceSlice(w, rotateStep, 1, -1, -1, face, position, direction);
				break;
			case TL:
				rotateFaceSlice(w, rotateStep, -1, -1, -1, face, position, direction);
				break;
			default:
				rotateAllFaces(w);
			}
			break;
		case 5:
			switch (direction) {
			case TOP:
				rotateFaceSlice(w, rotateStep, -1, -1, -1, face, position, direction);
				break;
			case TR:
				rotateFaceSlice(w, rotateStep, -1, -1, 1, face, position, direction);
				break;
			case BR:
				rotateFaceSlice(w, rotateStep, -1, 1, 1, face, position, direction);
				break;
			case BOTTOM:
				rotateFaceSlice(w, rotateStep, 1, 1, 1, face, position, direction);
				break;
			case BL:
				rotateFaceSlice(w, rotateStep, 1, 1, -1, face, position, direction);
				break;
			case TL:
				rotateFaceSlice(w, rotateStep, 1, -1, -1, face, position, direction);
				break;
			default:
				rotateAllFaces(w);
			}
			break;
		case 6:
			switch (direction) {
			case TR:
				rotateFaceSlice(w, rotateStep, -1, -1, -1, face, position, direction);
				break;
			case RIGHT:
				rotateFaceSlice(w, rotateStep, -1, -1, 1, face, position, direction);
				break;
			case BR:
				rotateFaceSlice(w, rotateStep, 1, -1, 1, face, position, direction);
				break;
			case BL:
				rotateFaceSlice(w, rotateStep, 1, 1, 1, face, position, direction);
				break;
			case LEFT:
				rotateFaceSlice(w, rotateStep, 1, 1, -1, face, position, direction);
				break;
			case TL:
				rotateFaceSlice(w, rotateStep, -1, 1, -1, face, position, direction);
				break;
			default:
				rotateAllFaces(w);
			}
			break;
		case 7:
			switch (direction) {
			case TOP:
				rotateFaceSlice(w, rotateStep, -1, 1, -1, face, position, direction);
				break;
			case TR:
				rotateFaceSlice(w, rotateStep, -1, 1, 1, face, position, direction);
				break;
			case BR:
				rotateFaceSlice(w, rotateStep, -1, -1, 1, face, position, direction);
				break;
			case BOTTOM:
				rotateFaceSlice(w, rotateStep, 1, -1, 1, face, position, direction);
				break;
			case BL:
				rotateFaceSlice(w, rotateStep, 1, -1, -1, face, position, direction);
				break;
			case TL:
				rotateFaceSlice(w, rotateStep, 1, 1, -1, face, position, direction);
				break;
			default:
				rotateAllFaces(w);
			}
			break;
		default:
			rotateAllFaces(w);
		}
/* 6 edge */
/* 0 1 0 rotate front edge CCW <=> 0 BL */
/* 0 -1 0 rotate front edge CW <=> 0 TR */
/* 1 0 0 rotate left edge CW <=> 0 BOTTOM */
/* -1 0 0 rotate left edge CCW <=> 0 TOP */
/* 0 0 1 rotate right edge CCW <=> 0 LEFT */
/* 0 0 -1 rotate right edge CW <=> 0 RIGHT */
	} else /* if (style == PERIOD4) */ {
		rotateStep = (float) w->octGL.rotateStep;
		/*if ((face == 1 || face == 2) && (dir == TR || dir == BL))
			dir = (dir + MAX_ORIENT / 2) % MAX_ORIENT;*/
		if (face < 4) {
			switch (direction) {
			case TR:
				rotateCornerSlice(w, rotateStep, 0, 0, -1, face, position, direction);
				break;
			case BR:
				rotateCornerSlice(w, rotateStep, 1, 0, 0, face, position, direction);
				break;
			case BL:
				rotateCornerSlice(w, rotateStep, 0, 0, 1, face, position, direction);
				break;
			case TL:
				rotateCornerSlice(w, rotateStep, -1, 0, 0, face, position, direction);
				break;
			case CW:
				rotateCornerSlice(w, rotateStep, 0, -1, 0, face, position, direction);
				break;
			case CCW:
				rotateCornerSlice(w, rotateStep, 0, 1, 0, face, position, direction);
				break;
			default:
				rotateAllCorners(w);
			}
		} else {
			switch (direction) {
			case TR:
				rotateCornerSlice(w, rotateStep, -1, 0, 0, face, position, direction);
				break;
			case BR:
				rotateCornerSlice(w, rotateStep, 0, 0, 1, face, position, direction);
				break;
			case BL:
				rotateCornerSlice(w, rotateStep, 1, 0, 0, face, position, direction);
				break;
			case TL:
				rotateCornerSlice(w, rotateStep, 0, 0, -1, face, position, direction);
				break;
			case CW:
				rotateCornerSlice(w, rotateStep, 0, 1, 0, face, position, direction);
				break;
			case CCW:
				rotateCornerSlice(w, rotateStep, 0, -1, 0, face, position, direction);
				break;
			default:
				rotateAllCorners(w);
			}
		}
	}
}

void
movePiecesGL(OctGLWidget w, int face, RTT rtt, int direction,
		int style, Boolean control, int fast)
{
	int i, f;

	w->octGL.movement.face = face;
	w->octGL.movement.position = toPosition(rtt);
	w->octGL.movement.direction = direction;
	w->octGL.movement.style = style;
	w->octGL.movement.control = control;
	w->octGL.rotateStep = 0.0;
	w->octGL.angleStep = 0.0;
	f = (w->octGL.numTurnInc < fast) ? 1 : fast;
	for (i = 0; i < w->octGL.numTurnInc / f; i++) {
		double increment = (360.0 / style) * f / w->octGL.numTurnInc;
		w->octGL.rotateStep += increment;
		/* 6 or 8 possibles */
		/*if (rotateDir[face][direction] == -1)*/
		drawAllPiecesGL(w);
		Sleep((unsigned int) ((w->oct.delay /
			(w->octGL.numTurnInc * f)) * 40.0));
		w->oct.currentFace = -1;
		w->oct.currentPosition = -1;
	}
	w->octGL.angleStep = 0.0;
	w->octGL.movement.face = NO_FACE;
	w->octGL.movement.position = NO_POSITION;
	w->octGL.movement.direction = NO_DEPTH;
	w->octGL.movement.style = NO_STYLE;
	w->octGL.movement.control = False;
}

void
drawAllPiecesGL(OctGLWidget w)
{
#ifdef WINVER
	wglMakeCurrent(w->core.hDC, hRC);
#else
	if (!glXMakeCurrent(XtDisplay(w), XtWindow(w), *glXContext)) {
		DISPLAY_WARNING("Draw All GL error");
	}
#endif
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glPushMatrix();
	glTranslate(0.0, 0.0, -10.0);
	if (w->core.height > w->core.width)
		glScalef(SCALE, (SCALE * (float) w->core.width / (float) w->core.height), SCALE);
	else
		glScalef((SCALE * (float) w->core.height / (float) w->core.width), SCALE, SCALE);
	switch (w->oct.view) {
	case 0: /* -<  vertical */
		glRotatef((GLfloat) w->octGL.step / (GLfloat) 2.5, 0, 1, 0);
		glRotatef((GLfloat) w->octGL.step / (GLfloat) 2.0, 1, 0, 0);
		break;
	case 1: /* ^  !vertical */
		glRotatef((GLfloat) w->octGL.step / (GLfloat) 2.5, 1, 0, 0);
		glRotatef((GLfloat) w->octGL.step / (GLfloat) 2.0, 0, 1, 0);
		break;
	case 2: /* -<  vertical */
		glRotatef((GLfloat) (-w->octGL.step) / (GLfloat) 2.5, 0, 1, 0);
		glRotatef((GLfloat) (-3 * w->octGL.step) / (GLfloat) 2.0, 1, 0, 0);
		break;
	case 3: /* Y  !vertical */
		glRotatef((GLfloat) (-w->octGL.step) / (GLfloat) 2.5, 1, 0, 0);
		glRotatef((GLfloat) (-3 * w->octGL.step) / (GLfloat) 2.0, 0, 1, 0);
		break;
	default:
		break;
	}
	drawOcta(w);
	glPopMatrix();
	glFlush();
#ifdef WINVER
	SwapBuffers(w->core.hDC);
#else
	glXSwapBuffers(XtDisplay(w), XtWindow(w));
#endif
}

/* UNUSED */
/*void
drawFrameGL(OctGLWidget w, Boolean focus)
{
}*/

static RTT 
normalizePosition(float x, float y, int size)
{
	float xf, yf;
	int xi, yi;
	RTT rtt;

	xf = (x * (float) size + (float) size) / (float) 2.0;
	yf = (y * (float) size + (float) size) / (float) 2.0;
	xi = (int) xf;
	if (xi < 0)
		xi = 0;
	if (xi >= size)
		xi = size - 1;
	yi = (int) yf;
	if (yi < 0)
		xi = 0;
	if (yi >= size)
		yi = size - 1;
#ifdef DEBUG
	(void) printf("xf %g, yf %g: xi %d, yi %d\n", xf, yf, xi, yi);
#endif
	rtt.row = xi; /* size 3: 0; 1, 2, 3; 4, 5, 6, 7, 8 */
	rtt.trbl = yi; /* size 3: 0, 1, 2, 4, 5; 3, 6, 7; 8 */
	rtt.tlbr = yi; /* size 3: 0, 2, 3, 7, 8; 2, 5, 6; 4 */
	return rtt;
}

Boolean
selectPiecesGL(OctGLWidget w, int x, int y, int *face, RTT *rtt)
{
	/* Using gluUnProject By: Luke Benstead */
	/* http://nehe.gamedev.net/data/articles/article.asp?article=13 */

	GLint viewport[4];
	GLdouble modelview[16];
	GLdouble projection[16];
	GLfloat winX, winY, winZ;
	GLdouble posX, posY, posZ;
	Matrix a, b, r;
	Vector t, world, nw;

	glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
	glGetDoublev(GL_PROJECTION_MATRIX, projection);
	glGetIntegerv(GL_VIEWPORT, viewport);

	winX = (float) x;
	winY = (float) viewport[3] - (float) y;
	glReadPixels(x, (int) winY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT,
		&winZ);
	gluUnProject(winX, winY, winZ, modelview, projection, viewport,
		&(posX), &(posY), &(posZ));
	t[0] = (float) posX;
	t[1] = (float) posY;
	t[2] = (float) (posZ + 10);
	if (w->core.height > w->core.width)
		t[1] *= (float) w->core.height / (float) w->core.width;
	else
		t[0] *= (float) w->core.width / (float) w->core.height;
	*face = -1;
	/* *position = -1; */
	if (winZ == 1) {
		return False;
	}
	world[0] = t[0], world[1] = t[1], world[2] = t[2];
	switch (w->oct.view) {
	case 0: /* -<  vertical */
		setMatrix((float) (-w->octGL.step) / (float) 2.0, 1.0, 0.0, 0.0, a);
		setMatrix((float) (-w->octGL.step) / (float) 2.5, 0.0, 1.0, 0.0, b);
		matrixMatrix(a, b, r);
		matrixVector(r, t, world);
		nw[0] = -world[0] / (float) 2.0;
		nw[1] = world[1] / (float) 2.0;
		nw[2] = world[2] / (float) 2.0;
		if (nw[0] >= nw[2] && nw[1] >= nw[2]) {
			*face = 0;
			*rtt = normalizePosition(world[0], world[2], w->oct.size);
		} else if (nw[1] >= nw[0] && nw[2] >= nw[0]) {
			*face = 1;
			*rtt = normalizePosition(world[2], -world[1], w->oct.size);
		} else if (nw[0] >= nw[1] && nw[2] >= nw[1]) {
			*face = 2;
			*rtt = normalizePosition(world[0], -world[1], w->oct.size);
		}
		break;
	case 1: /* ^  !vertical */
		setMatrix((float) (3 * w->octGL.step) / (float) 2.0, 0.0, 1.0, 0.0, a);
		setMatrix((float) w->octGL.step / (float) 2.65, 1.0, 0.0, 0.0, b);
		matrixMatrix(a, b, r);
		matrixVector(r, t, world);
		nw[0] = -world[0] / (float) 2.0;
		nw[1] = world[1] / (float) 2.0;
		nw[2] = world[2] / (float) 2.0;
		if (nw[0] <= nw[1] && nw[0] <= nw[2]) {
			*face = 0;
			*rtt = normalizePosition(-world[2], -world[1], w->oct.size);
		} else if (nw[1] <= nw[0] && nw[1] <= nw[2]) {
			*face = 2;
			*rtt = normalizePosition(world[0], -world[2], w->oct.size);
		} else if (nw[2] <= nw[0] && nw[2] <= nw[1]) {
			*face = 1;
			*rtt = normalizePosition(world[0], world[1], w->oct.size);
		}
		break;
	case 2: /* -<  vertical */
		setMatrix((float) (3 * w->octGL.step) / (float) 2.0, 1.0, 0.0, 0.0, a);
		setMatrix((float) w->octGL.step / (float) 2.65, 0.0, 1.0, 0.0, b);
		matrixMatrix(a, b, r);
		matrixVector(r, t, world);
		nw[0] = -world[0] / (float) 2.0;
		nw[1] = world[1] / (float) 2.0;
		nw[2] = world[2] / (float) 2.0;
		if (nw[1] >= nw[0] && nw[1] >= nw[2]) {
			*face = 0;
			*rtt = normalizePosition(world[0], world[2], w->oct.size);
		} else if (nw[0] >= nw[1] && nw[0] >= nw[2]) {
			*face = 1;
			*rtt = normalizePosition(world[2], -world[1], w->oct.size);
		} else if (nw[2] >= nw[0] && nw[2] >= nw[1]) {
			*face = 2;
			*rtt = normalizePosition(world[0], -world[1], w->oct.size);
		}
		*face = 3;
		break;
	case 3: /* Y  !vertical */
		setMatrix((float) (-w->octGL.step) / (float) 2.0, 0.0, 1.0, 0.0, a);
		setMatrix((float) (-w->octGL.step) / (float) 2.5, 1.0, 0.0, 0.0, b);
		matrixMatrix(a, b, r);
		matrixVector(r, t, world);
		nw[0] = -world[0] / (float) 2.0;
		nw[1] = world[1] / (float) 2.0;
		nw[2] = world[2] / (float) 2.0;
		if (nw[0] <= nw[1] && nw[0] <= nw[2]) {
			*face = 0;
			*rtt = normalizePosition(-world[2], -world[1], w->oct.size);
		} else if (nw[1] <= nw[0] && nw[1] <= nw[2]) {
			*face = 1;
			*rtt = normalizePosition(world[0], -world[2], w->oct.size);
		} else if (nw[2] <= nw[0] && nw[2] <= nw[1]) {
			*face = 2;
			*rtt = normalizePosition(world[0], world[1], w->oct.size);
		}
		*face = 3;
		break;
	default:
		break;
	}
#ifdef DEBUG
	(void) printf("x %d, y %d\n", x, y);
	(void) printf(" wx %g, wy %g, wz %g\n", winX, winY, winZ);
	(void) printf("  px %g, py %g, pz %g\n", posX, posY, posZ);
	(void) printf("   tx %g, ty %g, tz %g\n", t[0], t[1], t[2]);
	(void) printf("    rx %g, ry %g, rz %g\n",
		world[0], world[1], world[2]);
	(void) printf("    row %d, trbl %d, tlbr %d\n",
		rtt->row, rtt->trbl, rtt->tlbr);
	(void) printf("     face %d, pos %d\n", *face, *toPosition(*rtt));
#endif
	/* FIXME need to determine face and position
	return True;*/
	return False;
}

Boolean
narrowSelectionGL(OctGLWidget w, int style,
		int *face, RTT *rtt, int *direction)
{
	switch (*direction) {
	case BR:
		switch (w->oct.view) {
		case 0:
			switch (*face) {
			case 1:
				*direction = RIGHT;
				break;
			case 2:
				*direction = TR;
				break;
			default:
				*direction = IGNORE_DIR;
				break;
			}
			break;
		case 1:
			switch (*face) {
			case 1:
				*direction = BOTTOM;
				break;
			case 2:
				*direction = RIGHT;
				break;
			default:
				*direction = IGNORE_DIR;
				break;
			}
			break;
		case 2:
			switch (*face) {
			case 3:
				*direction = RIGHT;
				break;
			default:
				*direction = IGNORE_DIR;
				break;
			}
			break;
		case 3:
			switch (*face) {
			case 3:
				*direction = LEFT;
				break;
			default:
				*direction = IGNORE_DIR;
				break;
			}
			break;
		}
		break;
	case TL:
		switch (w->oct.view) {
		case 0:
			switch (*face) {
			case 1:
				*direction = LEFT;
				break;
			case 2:
				*direction = BL;
				break;
			default:
				*direction = IGNORE_DIR;
				break;
			}
			break;
		case 1:
			switch (*face) {
			case 1:
				*direction = TOP;
				break;
			case 2:
				*direction = LEFT;
				break;
			default:
				*direction = IGNORE_DIR;
				break;
			}
			break;
		case 2:
			switch (*face) {
			case 3:
				*direction = LEFT;
				break;
			default:
				*direction = IGNORE_DIR;
				break;
			}
			break;
		case 3:
			switch (*face) {
			case 3:
				*direction = RIGHT;
				break;
			default:
				*direction = IGNORE_DIR;
				break;
			}
			break;
		}
		break;
	case CCW:
		switch (w->oct.view) {
		case 0:
		case 1:
			switch (*face) {
			case 0:
				*direction = LEFT;
				break;
			case 1:
				*direction = TOP;
				break;
			case 2:
				*direction = TR;
				break;
			default:
				*direction = IGNORE_DIR;
				break;
			}
			break;
		case 2:
		case 3:
			*face = 0;
			*direction = RIGHT;
			break;
		}
		break;
	case CW:
		switch (w->oct.view) {
		case 0:
		case 1:
			switch (*face) {
			case 0:
				*direction = RIGHT;
				break;
			case 1:
				*direction = BOTTOM;
				break;
			case 2:
				*direction = BL;
				break;
			default:
				*direction = IGNORE_DIR;
				break;
			}
			break;
		case 2:
		case 3:
			*face = 0;
			*direction = LEFT;
			break;
		}
		break;
	case TOP:
		switch (w->oct.view) {
		case 0:
			switch (*face) {
			case 0:
				*direction = TR;
				break;
			case 1:
				*direction = TOP;
				break;
			case 2:
				*direction = LEFT;
				break;
			default:
				*direction = IGNORE_DIR;
				break;
			}
			break;
		case 1:
			switch (*face) {
			case 0:
			case 1:
				*direction = TR;
				break;
			default:
				*direction = IGNORE_DIR;
				break;
			}
			break;
		case 2:
			switch (*face) {
			case 3:
				*direction = TOP;
				break;
			default:
				*direction = IGNORE_DIR;
				break;
			}
			break;
		case 3:
			*direction = IGNORE_DIR;
			break;
		}
		break;
	case TR:
		switch (w->oct.view) {
		case 0:
			switch (*face) {
			case 0:
				*direction = RIGHT;
				break;
			case 1:
				*direction = TR;
				break;
			default:
				*direction = IGNORE_DIR;
				break;
			}
			break;
		case 1:
			switch (*face) {
			case 0:
				*direction = RIGHT;
				break;
			case 2:
				*direction = TOP;
				break;
			default:
				*direction = IGNORE_DIR;
				break;
			}
			break;
		case 2:
			switch (*face) {
			case 3:
				*direction = TR;
				break;
			default:
				*direction = IGNORE_DIR;
				break;
			}
			break;
		case 3:
			switch (*face) {
			case 3:
				*direction = BOTTOM;
				break;
			default:
				*direction = IGNORE_DIR;
				break;
			}
			break;
		}
		break;
	case RIGHT:
		switch (w->oct.view) {
		case 0:
			switch (*face) {
			case 0:
				*direction = BOTTOM;
				break;
			case 2:
				*direction = TOP;
				break;
			default:
				*direction = IGNORE_DIR;
				break;
			}
			break;
		case 1:
			switch (*face) {
			case 0:
				*direction = BOTTOM;
				break;
			case 1:
				*direction = RIGHT;
				break;
			case 2:
				*direction = TR;
				break;
			default:
				*direction = IGNORE_DIR;
				break;
			}
			break;
		case 2:
			*direction = IGNORE_DIR;
			break;
		case 3:
			switch (*face) {
			case 3:
				*direction = BL;
				break;
			default:
				*direction = IGNORE_DIR;
				break;
			}
			break;
		}
		break;
	case BOTTOM:
		switch (w->oct.view) {
		case 0:
			switch (*face) {
			case 0:
				*direction = BL;
				break;
			case 1:
				*direction = BOTTOM;
				break;
			case 2:
				*direction = RIGHT;
				break;
			default:
				*direction = IGNORE_DIR;
				break;
			}
			break;
		case 1:
			switch (*face) {
			case 0:
			case 1:
				*direction = BL;
				break;
			default:
				*direction = IGNORE_DIR;
				break;
			}
			break;
		case 2:
			switch (*face) {
			case 3:
				*direction = BOTTOM;
				break;
			default:
				*direction = IGNORE_DIR;
				break;
			}
			break;
		case 3:
			switch (*face) {
			case 3:
				*direction = BL;
				break;
			default:
				*direction = IGNORE_DIR;
				break;
			}
			break;
		}
		break;
	case BL:
		switch (w->oct.view) {
		case 0:
			switch (*face) {
			case 0:
				*direction = LEFT;
				break;
			case 1:
				*direction = BL;
				break;
			default:
				*direction = IGNORE_DIR;
				break;
			}
			break;
		case 1:
			switch (*face) {
			case 0:
				*direction = LEFT;
				break;
			case 2:
				*direction = BOTTOM;
				break;
			default:
				*direction = IGNORE_DIR;
				break;
			}
			break;
		case 2:
			switch (*face) {
			case 3:
				*direction = BL;
				break;
			default:
				*direction = IGNORE_DIR;
				break;
			}
			break;
		case 3:
			switch (*face) {
			case 3:
				*direction = TOP;
				break;
			default:
				*direction = IGNORE_DIR;
				break;
			}
			break;
		}
		break;
	case LEFT:
		switch (w->oct.view) {
		case 0:
			switch (*face) {
			case 0:
				*direction = TOP;
				break;
			case 2:
				*direction = BOTTOM;
				break;
			default:
				*direction = IGNORE_DIR;
				break;
			}
			break;
		case 1:
			switch (*face) {
			case 0:
				*direction = TOP;
				break;
			case 1:
				*direction = LEFT;
				break;
			case 2:
				*direction = BL;
				break;
			default:
				*direction = IGNORE_DIR;
				break;
			}
			break;
		case 2:
			*direction = IGNORE_DIR;
			break;
		case 3:
			switch (*face) {
			case 3:
				*direction = TR;
				break;
			default:
				*direction = IGNORE_DIR;
				break;
			}
			break;
		}
		break;
	default:
		break;
	}
	return True;
}

#ifdef WINVER
static Boolean
setupPixelFormat(OctGLWidget w, BYTE type, DWORD flags)
{
	PIXELFORMATDESCRIPTOR pfd;
	int pixelFormat;

	memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
	pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
	pfd.nVersion = 1;
	pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | flags;
	pfd.dwLayerMask = PFD_MAIN_PLANE;
	/*pfd.cColorBits = 8;
	pfd.cDepthBits = 16;*/
	pfd.iPixelType = type;
	pfd.cColorBits = 24;
	pfd.cDepthBits = 32;

	if ((pixelFormat = ChoosePixelFormat(w->core.hDC, &pfd)) == 0) {
		DWORD err;
		char *buf1;

		err = GetLastError();
		/* 6 ERROR_INVALID_HANDLE */
		intCat(&buf1, "ChoosePixelFormat failed ", (int) err);
		DISPLAY_WARNING(buf1);
		free(buf1);
		return FALSE;
	}

	if (SetPixelFormat(w->core.hDC, pixelFormat, &pfd) == FALSE) {
		MessageBox(NULL, "SetPixelFormat failed", "Error", MB_OK);
		return FALSE;
	}
	DescribePixelFormat(w->core.hDC, pixelFormat,
		sizeof(PIXELFORMATDESCRIPTOR), &pfd);
	return TRUE;
}

#else

static Boolean
setValuesPuzzleGL(Widget current, Widget request, Widget renew)
{
	OctGLWidget c = (OctGLWidget) current, w = (OctGLWidget) renew;
	Boolean redraw = False;

	if (w->oct.view != c->oct.view) {
		resizePuzzleGL(w);
		redraw = True;
	}
	if (w->oct.size != c->oct.size) {
		resetPieces((OctWidget) w);
		resizePuzzleGL(w);
		redraw = True;
	}
	if (w->oct.delay != c->oct.delay) {
		w->octGL.numTurnInc = ((w->oct.delay < MAX_TURN_INC) ?
			w->oct.delay + 1 : MAX_TURN_INC);
	}
	return (redraw);
}

static GLXContext *
initGL(OctGLWidget w) {
	XVisualInfo xviIn, *xviOut;
	int numVis;

	/*XGetWindowAttributes(XtDisplay(w), XtWindow(w), &xgwa); */
	xviIn.screen = DefaultScreen(XtDisplay(w));
	xviIn.visualid = XVisualIDFromVisual(DefaultVisual(XtDisplay(w),
		xviIn.screen));
	xviOut = XGetVisualInfo(XtDisplay(w), VisualScreenMask | VisualIDMask,
		&xviIn, &numVis);
	if (!xviOut) {
		XtWarning("Could not get XVisualInfo");
		return (GLXContext *) NULL;
	}
	if (glXContext)
		free(glXContext);
	if ((glXContext = (GLXContext *) malloc(sizeof (GLXContext))) ==
			NULL) {
		DISPLAY_ERROR("Not enough memory for glx info, exiting.");
	}
	/* assertion "glx_dpy" failed on Cygwin */
	if (!glXQueryExtension(XtDisplay(w), NULL, NULL)) {
		XtWarning("Could not find GLX");
		return (GLXContext *) NULL;
	}
	*glXContext = glXCreateContext(XtDisplay(w), xviOut, 0, GL_TRUE);
	(void) XFree((char *) xviOut);
	if (!*glXContext) {
		XtWarning("Could not create rendering context");
		return (GLXContext *) NULL;
	}
	return glXContext;
}
#endif

#ifndef WINVER
static
#endif
void
resizePuzzleGL(OctGLWidget w)
{
#ifdef WINVER
	RECT rect;

	/* Determine size of client area */
	(void) GetClientRect(w->core.hWnd, &rect);
	w->core.width = rect.right;
	w->core.height = rect.bottom;
#endif
	glViewport(0, 0, (GLint) w->core.width, (GLint) w->core.height);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 15.0);
	glMatrixMode(GL_MODELVIEW);
}

static void
makeCurrentGL(OctGLWidget w)
{
	GLboolean rgbaMode;

#ifdef WINVER
	wglMakeCurrent(w->core.hDC, hRC);
#else
	if (!glXMakeCurrent(XtDisplay(w), XtWindow(w), *glXContext)) {
		DISPLAY_WARNING("GL error");
	}
#endif
	madeCurrent = True;
	/* True Color junk */
	glGetBooleanv(GL_RGBA_MODE, &rgbaMode);
	if (!rgbaMode) {
#ifdef WINVER
		glClearIndex(0.0);
#else
		glIndexi(WhitePixel(XtDisplay(w),
			DefaultScreen(XtDisplay(w))));
		glClearIndex((float) BlackPixel(XtDisplay(w),
			DefaultScreen(XtDisplay(w))));
#endif
	}
	resizePuzzleGL(w);

	glDrawBuffer(GL_BACK);
	glClearDepth(1.0);
	glClearColor(face_material[NO_FACE][0], face_material[NO_FACE][1],
		face_material[NO_FACE][2], face_material[NO_FACE][3]);
	glColor3f(1.0, 1.0, 1.0);

	glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
	glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
	glLightfv(GL_LIGHT0, GL_POSITION, position0);
	glLightfv(GL_LIGHT1, GL_AMBIENT, ambient);
	glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse);
	glLightfv(GL_LIGHT1, GL_POSITION, position1);
	glLightfv(GL_LIGHT2, GL_AMBIENT, ambient);
	glLightfv(GL_LIGHT2, GL_DIFFUSE, diffuse);
	glLightfv(GL_LIGHT2, GL_POSITION, position2);
	glLightfv(GL_LIGHT3, GL_AMBIENT, ambient);
	glLightfv(GL_LIGHT3, GL_DIFFUSE, diffuse);
	glLightfv(GL_LIGHT3, GL_POSITION, position3);
	glLightfv(GL_LIGHT4, GL_AMBIENT, ambient);
	glLightfv(GL_LIGHT4, GL_DIFFUSE, diffuse);
	glLightfv(GL_LIGHT4, GL_POSITION, position4);
	glLightfv(GL_LIGHT5, GL_AMBIENT, ambient);
	glLightfv(GL_LIGHT5, GL_DIFFUSE, diffuse);
	glLightfv(GL_LIGHT5, GL_POSITION, position5);
	glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
	glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside);
	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);
	glEnable(GL_LIGHT1);
	glEnable(GL_LIGHT2);
	glEnable(GL_LIGHT3);
	glEnable(GL_LIGHT4);
	glEnable(GL_LIGHT5);
	glEnable(GL_DEPTH_TEST);
	glEnable(GL_NORMALIZE);
	glEnable(GL_CULL_FACE);
	glShadeModel(GL_FLAT);
	glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, front_shininess);
	glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, front_specular);

	w->octGL.step = 90;
	w->octGL.rotateStep = 0.0;
}

#ifndef WINVER
static void
initializePuzzleGL(Widget request, Widget renew)
{
	OctGLWidget w = (OctGLWidget) renew;
	int i;

	setAllColors((OctWidget) w);
	if (initGL(w) == (GLXContext *) NULL) {
		w->oct.dim = 0;
		return;
	}
	w->oct.dim = 4; /* 2 and 3 already taken */
	for (i = 0; i < MAX_FACES + 2; i++)
		pickColor(w, i, w->oct.mono, face_material[i]);
	w->octGL.numTurnInc = ((w->oct.delay < MAX_TURN_INC) ?
		w->oct.delay + 1 : MAX_TURN_INC);
	resizePuzzleGL(w);
}
#endif

#ifndef WINVER
static
#endif
void
exposePuzzleGL(
#ifdef WINVER
OctGLWidget w
#else
Widget renew, XEvent *event, Region region
#endif
)
{
#ifdef WINVER
	if (hRC == NULL) {
		BYTE type;
		int i;
		DWORD flags = PFD_DOUBLEBUFFER;

#if 1
		type = PFD_TYPE_RGBA;
#else
		type = PFD_TYPE_COLORINDEX;
#endif
		(void) setupPixelFormat(w, type, flags);
		hRC = wglCreateContext(w->core.hDC);
		w->octGL.movement.face = NO_FACE;
		w->octGL.movement.position = NO_POSITION;
		w->octGL.movement.direction = NO_DEPTH;
		w->octGL.movement.style = NO_STYLE;
		w->octGL.movement.control = False;
		w->octGL.rotateStep = 0.0;
		w->octGL.angleStep = 0.0;
		w->oct.dim = 4; /* 2 and 3 already taken */
		for (i = 0; i < MAX_FACES + 2; i++)
			pickColor(w, i, w->oct.mono, face_material[i]);
		w->octGL.numTurnInc = ((w->oct.delay < MAX_TURN_INC) ?
			w->oct.delay + 1 : MAX_TURN_INC);
		resizePuzzleGL(w);
	}
#else
	OctGLWidget w = (OctGLWidget) renew;

	if (!w->core.visible)
		return;
	if (w->oct.dim != 4)
		return;
#endif
	if (!madeCurrent) {
		makeCurrentGL(w);
	}
	/*drawFrameGL(w, w->oct.focus);*/
	drawAllPiecesGL(w);
}

#ifndef WINVER
static void
movePuzzleGLTl(OctGLWidget w, XEvent *event, char **args, int nArgs)
{
	movePuzzleInput((OctWidget) w, event->xbutton.x, event->xbutton.y,
		TL,
		(int) (event->xkey.state & (ShiftMask | LockMask)),
		(int) (event->xkey.state & ControlMask));
}

static void
movePuzzleGLTop(OctGLWidget w, XEvent *event, char **args, int nArgs)
{
	movePuzzleInput((OctWidget) w, event->xbutton.x, event->xbutton.y,
		TOP,
		(int) (event->xkey.state & (ShiftMask | LockMask)),
		(int) (event->xkey.state & ControlMask));
}

static void
movePuzzleGLTr(OctGLWidget w, XEvent *event, char **args, int nArgs)
{
	movePuzzleInput((OctWidget) w, event->xbutton.x, event->xbutton.y,
		TR,
		(int) (event->xkey.state & (ShiftMask | LockMask)),
		(int) (event->xkey.state & ControlMask));
}

static void
movePuzzleGLLeft(OctGLWidget w, XEvent *event, char **args, int nArgs)
{
	movePuzzleInput((OctWidget) w, event->xbutton.x, event->xbutton.y,
		LEFT,
		(int) (event->xkey.state & (ShiftMask | LockMask)),
		(int) (event->xkey.state & ControlMask));
}

static void
movePuzzleGLRight(OctGLWidget w, XEvent *event, char **args, int nArgs)
{
	movePuzzleInput((OctWidget) w, event->xbutton.x, event->xbutton.y,
		RIGHT,
		(int) (event->xkey.state & (ShiftMask | LockMask)),
		(int) (event->xkey.state & ControlMask));
}

static void
movePuzzleGLBl(OctGLWidget w, XEvent *event, char **args, int nArgs)
{
	movePuzzleInput((OctWidget) w, event->xbutton.x, event->xbutton.y,
		BL,
		(int) (event->xkey.state & (ShiftMask | LockMask)),
		(int) (event->xkey.state & ControlMask));
}

static void
movePuzzleGLBottom(OctGLWidget w, XEvent *event, char **args, int nArgs)
{
	movePuzzleInput((OctWidget) w, event->xbutton.x, event->xbutton.y,
		BOTTOM,
		(int) (event->xkey.state & (ShiftMask | LockMask)),
		(int) (event->xkey.state & ControlMask));
}

static void
movePuzzleGLBr(OctGLWidget w, XEvent *event, char **args, int nArgs)
{
	movePuzzleInput((OctWidget) w, event->xbutton.x, event->xbutton.y,
		BR,
		(int) (event->xkey.state & (ShiftMask | LockMask)),
		(int) (event->xkey.state & ControlMask));
}
#endif
#else
int x = 0; /* non empty source */
#endif
