aboutsummaryrefslogtreecommitdiff
path: root/src/graph/view3D/volume3d.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/graph/view3D/volume3d.c')
-rw-r--r--src/graph/view3D/volume3d.c879
1 files changed, 879 insertions, 0 deletions
diff --git a/src/graph/view3D/volume3d.c b/src/graph/view3D/volume3d.c
new file mode 100644
index 00000000..aab93491
--- /dev/null
+++ b/src/graph/view3D/volume3d.c
@@ -0,0 +1,879 @@
+/*
+ Copyright (C) 1991-2002, The Numerical ALgorithms Group Ltd.
+ All rights reserved.
+ Copyright (C) 2007-2008, Gabriel Dos Reis.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#define _VOLUME3D_C
+#include "axiom-c-macros.h"
+
+#include <math.h>
+#include <string.h>
+
+#include "header.h"
+#include "cpanel.h"
+#include "process.h"
+#include "volume.h"
+#include "../include/purty/volume.bitmap"
+#include "../include/purty/volume.mask"
+
+
+
+#include "XSpadFill.H1"
+#include "Gfun.H1"
+#include "all_3d.H1"
+
+#define eyeDistMessX (frusX(eyeWinX+27))
+#define eyeDistMessY (frusY(eyeWinY-5))
+#define hitherMessX (frusX(hitherWinX+15))
+#define hitherMessY (frusY(hitherWinY))
+
+#define clipXMessX (control->buttonQueue[clipXBut].buttonX + \
+ control->buttonQueue[clipXBut].xHalf)
+#define clipXMessY (control->buttonQueue[clipXBut].buttonY + 2)
+#define clipYMessX (control->buttonQueue[clipYBut].buttonX + \
+ control->buttonQueue[clipYBut].buttonWidth-2)
+#define clipYMessY (control->buttonQueue[clipYBut].buttonY + \
+ control->buttonQueue[clipYBut].yHalf)
+#define clipZMessX (control->buttonQueue[clipZBut].buttonX + \
+ control->buttonQueue[clipZBut].xHalf+4)
+#define clipZMessY (control->buttonQueue[clipZBut].buttonY + \
+ control->buttonQueue[clipZBut].yHalf-4)
+
+#define volumeCursorForeground monoColor(68)
+#define volumeCursorBackground monoColor(197)
+
+#define hitherBoxColor monoColor(141)
+#define hitherBoxTop (frustrumMidY - 10)
+#define hitherBoxHeight 20
+
+#define clipButtonColor 144
+#define toggleColor 42
+#define arcColor 75
+
+#define arcSize 6
+#define tinyArc 5
+#define blank 4
+#define toggleX 190
+#define toggleY 280
+
+#define oldWay
+
+#define frusX(x) (control->buttonQueue[frustrumBut].buttonX + x)
+#define frusY(y) (control->buttonQueue[frustrumBut].buttonY + y)
+
+#define clipMessX 7
+#define clipMessY (control->buttonQueue[clipXBut].buttonY + 15)
+ /* someotherFont holds title font (see main.c) */
+#define clipMessDy (globalFont->max_bounds.ascent/2 + \
+ globalFont->max_bounds.descent)
+static char *clipMess = "Clip Volume";
+
+#define eyeMess1Dy clipMessDy
+#define eyeMess1X 7
+#define eyeMess1Y (frustrumY + 40 + 3*eyeMess1Dy)
+static char *eyeMess1 = "Eye";
+
+#define eyeMess2X (globalFont->max_bounds.width + 14)
+#define eyeMess2Y (frustrumY + 40)
+#define eyeMess2Dy eyeMess1Dy
+static char *eyeMess2 = "Reference";
+
+
+ /* global stuff */
+int flatClipBoxX[8], flatClipBoxY[8];
+
+
+
+
+/******************* volume buttons **********************/
+
+int
+#ifdef _NO_PROTO
+initVolumeButtons (volumeButtons)
+ buttonStruct *volumeButtons;
+#else
+initVolumeButtons (buttonStruct *volumeButtons)
+#endif
+{
+ int ii, num = 0;
+
+ ii = volumeReturn;
+ volumeButtons[ii].buttonX = 154;
+ volumeButtons[ii].buttonY = 370;
+ volumeButtons[ii].buttonWidth = 110;
+ volumeButtons[ii].buttonHeight = 24;
+ volumeButtons[ii].buttonKey = ii;
+ volumeButtons[ii].pot = no;
+ volumeButtons[ii].mask = buttonMASK;
+ volumeButtons[ii].text = "Return";
+ volumeButtons[ii].textColor = 52;
+ volumeButtons[ii].xHalf = volumeButtons[ii].buttonWidth/2;
+ volumeButtons[ii].yHalf = volumeButtons[ii].buttonHeight/2;
+ ++num;
+
+ ii = volumeAbort;
+ volumeButtons[ii].buttonX = 36;
+ volumeButtons[ii].buttonY = 370;
+ volumeButtons[ii].buttonWidth = 110;
+ volumeButtons[ii].buttonHeight = 24;
+ volumeButtons[ii].buttonKey = ii;
+ volumeButtons[ii].pot = no;
+ volumeButtons[ii].mask = buttonMASK;
+ volumeButtons[ii].text = "Abort";
+ volumeButtons[ii].textColor = 28;
+ volumeButtons[ii].xHalf = volumeButtons[ii].buttonWidth/2;
+ volumeButtons[ii].yHalf = volumeButtons[ii].buttonHeight/2;
+ ++num;
+
+ ii = frustrumBut;
+ volumeButtons[ii].buttonX = frustrumWindowX;
+ volumeButtons[ii].buttonY = frustrumWindowY;
+ volumeButtons[ii].buttonWidth = frustrumWindowWidth;
+ volumeButtons[ii].buttonHeight = frustrumWindowHeight;
+ volumeButtons[ii].buttonKey = ii;
+ volumeButtons[ii].pot = yes;
+ volumeButtons[ii].mask = potMASK;
+ volumeButtons[ii].text = "Frustrum Window";
+ volumeButtons[ii].textColor = frustrumColor;
+ volumeButtons[ii].xHalf = volumeButtons[ii].buttonWidth/2;
+ volumeButtons[ii].yHalf = volumeButtons[ii].buttonHeight/2;
+ ++num;
+
+ ii = perspectiveBut;
+ volumeButtons[ii].buttonX = toggleX;
+ volumeButtons[ii].buttonY = toggleY;
+ volumeButtons[ii].buttonWidth = 10;
+ volumeButtons[ii].buttonHeight = 10;
+ volumeButtons[ii].buttonKey = ii;
+ volumeButtons[ii].pot = no;
+ volumeButtons[ii].mask = potMASK;
+ volumeButtons[ii].text = "Perspective";
+ volumeButtons[ii].textColor = arcColor;
+ volumeButtons[ii].xHalf = volumeButtons[ii].buttonWidth/2;
+ volumeButtons[ii].yHalf = volumeButtons[ii].buttonHeight/2;
+ ++num;
+
+ ii = clipRegionBut;
+ volumeButtons[ii].buttonX = toggleX;
+ volumeButtons[ii].buttonY = toggleY+20;
+ volumeButtons[ii].buttonWidth = 10;
+ volumeButtons[ii].buttonHeight = 10;
+ volumeButtons[ii].buttonKey = ii;
+ volumeButtons[ii].pot = no;
+ volumeButtons[ii].mask = potMASK;
+ volumeButtons[ii].text = "Show Region";
+ volumeButtons[ii].textColor = arcColor;
+ volumeButtons[ii].xHalf = volumeButtons[ii].buttonWidth/2;
+ volumeButtons[ii].yHalf = volumeButtons[ii].buttonHeight/2;
+ ++num;
+
+ ii = clipSurfaceBut;
+ volumeButtons[ii].buttonX = toggleX;
+ volumeButtons[ii].buttonY = toggleY+40;
+ volumeButtons[ii].buttonWidth = 10;
+ volumeButtons[ii].buttonHeight = 10;
+ volumeButtons[ii].buttonKey = ii;
+ volumeButtons[ii].pot = no;
+ volumeButtons[ii].mask = potMASK;
+ volumeButtons[ii].text = "Clipping On";
+ volumeButtons[ii].textColor = arcColor;
+ volumeButtons[ii].xHalf = volumeButtons[ii].buttonWidth/2;
+ volumeButtons[ii].yHalf = volumeButtons[ii].buttonHeight/2;
+ ++num;
+
+ ii = clipXBut;
+ volumeButtons[ii].buttonX = clipXButX;
+ volumeButtons[ii].buttonY = clipXButY;
+ volumeButtons[ii].buttonWidth = majorAxis;
+ volumeButtons[ii].buttonHeight = minorAxis;
+ volumeButtons[ii].buttonKey = ii;
+ volumeButtons[ii].pot = yes;
+ volumeButtons[ii].mask = potMASK;
+ volumeButtons[ii].text = "Clip X";
+ volumeButtons[ii].textColor = clipButtonColor;
+ volumeButtons[ii].xHalf = volumeButtons[ii].buttonWidth/2;
+ volumeButtons[ii].yHalf = volumeButtons[ii].buttonHeight/2;
+ ++num;
+
+ ii = clipYBut;
+ volumeButtons[ii].buttonX = clipYButX;
+ volumeButtons[ii].buttonY = clipYButY;
+ volumeButtons[ii].buttonWidth = minorAxis;
+ volumeButtons[ii].buttonHeight = majorAxis;
+ volumeButtons[ii].buttonKey = ii;
+ volumeButtons[ii].pot = yes;
+ volumeButtons[ii].mask = potMASK;
+ volumeButtons[ii].text = "Clip Y";
+ volumeButtons[ii].textColor = clipButtonColor;
+ volumeButtons[ii].xHalf = volumeButtons[ii].buttonWidth/2;
+ volumeButtons[ii].yHalf = volumeButtons[ii].buttonHeight/2;
+ ++num;
+
+ ii = clipZBut;
+ volumeButtons[ii].buttonX = clipZButX;
+ volumeButtons[ii].buttonY = clipZButY;
+ volumeButtons[ii].buttonWidth = midAxis;
+ volumeButtons[ii].buttonHeight = midAxis;
+ volumeButtons[ii].buttonKey = ii;
+ volumeButtons[ii].pot = yes;
+ volumeButtons[ii].mask = potMASK;
+ volumeButtons[ii].text = "Clip Z";
+ volumeButtons[ii].textColor = clipButtonColor;
+ volumeButtons[ii].xHalf = volumeButtons[ii].buttonWidth/2;
+ volumeButtons[ii].yHalf = volumeButtons[ii].buttonHeight/2;
+ ++num;
+
+ return(num);
+}
+
+
+/*************************
+ * int makeVolumePanel() *
+ *************************/
+
+void
+#ifdef _NO_PROTO
+makeVolumePanel ()
+#else
+makeVolumePanel (void)
+#endif
+{
+
+ int i;
+ XSetWindowAttributes cwAttrib, controlAttrib;
+ XSizeHints sizehint;
+ Pixmap volumebits, volumemask;
+ XColor foreColor, backColor;
+
+ volumebits = XCreateBitmapFromData(dsply,rtWindow,volumeBitmap_bits,
+ volumeBitmap_width,volumeBitmap_height);
+ volumemask = XCreateBitmapFromData(dsply,rtWindow,volumeMask_bits,
+ volumeMask_width,volumeMask_height);
+ cwAttrib.background_pixel = backgroundColor;
+ cwAttrib.border_pixel = foregroundColor;
+ cwAttrib.event_mask = volumeMASK;
+ cwAttrib.colormap = colorMap;
+ cwAttrib.override_redirect = overrideManager;
+ foreColor.pixel = volumeCursorForeground;
+ XQueryColor(dsply,colorMap,&foreColor);
+ backColor.pixel = volumeCursorBackground;
+ XQueryColor(dsply,colorMap,&backColor);
+ cwAttrib.cursor = XCreatePixmapCursor(dsply,volumebits,volumemask,
+ &foreColor,&backColor,
+ volumeBitmap_x_hot,
+ volumeBitmap_y_hot);
+ volumeWindow = XCreateWindow(dsply,control->controlWindow,
+ -3,-3,controlWidth,controlHeight,3,
+ CopyFromParent,InputOutput,CopyFromParent,
+ controlCreateMASK,&cwAttrib);
+
+ sizehint.flags = USPosition | USSize;
+ sizehint.x = 0;
+ sizehint.y = 0;
+ sizehint.width = controlWidth;
+ sizehint.height = controlHeight;
+ /*** the None stands for icon pixmap ***/
+ XSetNormalHints(dsply,volumeWindow,&sizehint);
+ XSetStandardProperties(dsply,volumeWindow,"Volume Panel 3D",
+ "View Volume",None,NULL,0,&sizehint);
+
+ /*** volume frustrum window ***/
+
+ /*** do volume buttons ***/
+ initVolumeButtons(control->buttonQueue);
+ for (i=volumeButtonsStart; i<(volumeButtonsEnd); i++) {
+ controlAttrib.event_mask = (control->buttonQueue[i]).mask;
+ (control->buttonQueue[i]).self =
+ XCreateWindow(dsply,volumeWindow,
+ (control->buttonQueue[i]).buttonX,
+ (control->buttonQueue[i]).buttonY,
+ (control->buttonQueue[i]).buttonWidth,
+ (control->buttonQueue[i]).buttonHeight,
+ 0,0,InputOnly,CopyFromParent,
+ buttonCreateMASK,&controlAttrib);
+ XMakeAssoc(dsply,table,(control->buttonQueue[i]).self,
+ &((control->buttonQueue[i]).buttonKey));
+ XMapWindow(dsply,(control->buttonQueue[i]).self);
+ }
+
+} /* makeVolumePanel() */
+
+
+void
+#ifdef _NO_PROTO
+drawClipXBut ()
+#else
+drawClipXBut (void)
+#endif
+{
+
+ XClearArea(dsply,volumeWindow,clipXButX,clipXButY,
+ majorAxis+blank,minorAxis+blank,False);
+ GSetForeground(trashGC,(float)monoColor(toggleColor),Xoption);
+ GDrawLine(trashGC,volumeWindow,
+ (control->buttonQueue[clipXBut]).buttonX,
+ (control->buttonQueue[clipXBut]).buttonY +
+ (control->buttonQueue[clipXBut]).yHalf,
+ (control->buttonQueue[clipXBut]).buttonX +
+ (control->buttonQueue[clipXBut]).buttonWidth,
+ (control->buttonQueue[clipXBut]).buttonY +
+ (control->buttonQueue[clipXBut]).yHalf,Xoption);
+ GDrawLine(trashGC,volumeWindow,
+ (control->buttonQueue[clipXBut]).buttonX-3,
+ (control->buttonQueue[clipXBut]).buttonY +
+ (control->buttonQueue[clipXBut]).yHalf-3,
+ (control->buttonQueue[clipXBut]).buttonX,
+ (control->buttonQueue[clipXBut]).buttonY +
+ (control->buttonQueue[clipXBut]).yHalf,Xoption);
+ GDrawLine(trashGC,volumeWindow,
+ (control->buttonQueue[clipXBut]).buttonX-3,
+ (control->buttonQueue[clipXBut]).buttonY +
+ (control->buttonQueue[clipXBut]).yHalf+3,
+ (control->buttonQueue[clipXBut]).buttonX,
+ (control->buttonQueue[clipXBut]).buttonY +
+ (control->buttonQueue[clipXBut]).yHalf,Xoption);
+ GDrawLine(trashGC,volumeWindow,
+ (control->buttonQueue[clipXBut]).buttonX +
+ (control->buttonQueue[clipXBut]).buttonWidth+3,
+ (control->buttonQueue[clipXBut]).buttonY +
+ (control->buttonQueue[clipXBut]).yHalf-3,
+ (control->buttonQueue[clipXBut]).buttonX +
+ (control->buttonQueue[clipXBut]).buttonWidth,
+ (control->buttonQueue[clipXBut]).buttonY +
+ (control->buttonQueue[clipXBut]).yHalf,Xoption);
+ GDrawLine(trashGC,volumeWindow,
+ (control->buttonQueue[clipXBut]).buttonX +
+ (control->buttonQueue[clipXBut]).buttonWidth+3,
+ (control->buttonQueue[clipXBut]).buttonY +
+ (control->buttonQueue[clipXBut]).yHalf+3,
+ (control->buttonQueue[clipXBut]).buttonX +
+ (control->buttonQueue[clipXBut]).buttonWidth,
+ (control->buttonQueue[clipXBut]).buttonY +
+ (control->buttonQueue[clipXBut]).yHalf,Xoption);
+
+ GSetForeground(trashGC,(float)monoColor(arcColor),Xoption);
+ GFillArc(trashGC,volumeWindow,
+ (int)(xClipMinN * (majorAxis-tinyArc) + clipXButX), /* x value */
+ (int)(clipXButY + minorAxis/2 + 1), /* y value */
+ arcSize,arcSize,0,360*64,Xoption); /* 64 units per degree */
+ GFillArc(trashGC,volumeWindow,
+ (int)(xClipMaxN * (majorAxis-tinyArc) + clipXButX), /* x value */
+ (int)(clipXButY + minorAxis/2 - 7), /* y value */
+ arcSize,arcSize,0,360*64,Xoption); /* 64 units per degree */
+
+ GSetForeground(volumeGC,(float)monoColor(toggleColor),Xoption);
+ GDrawString(volumeGC,volumeWindow,clipXMessX,clipXMessY,"X",1,Xoption);
+
+}
+
+void
+#ifdef _NO_PROTO
+drawClipYBut ()
+#else
+drawClipYBut (void)
+#endif
+{
+
+ XClearArea(dsply,volumeWindow,clipYButX,clipYButY,
+ minorAxis+blank,majorAxis+blank,False);
+ GSetForeground(trashGC,(float)monoColor(toggleColor),Xoption);
+ GDrawLine(trashGC,volumeWindow,
+ (control->buttonQueue[clipYBut]).buttonX +
+ (control->buttonQueue[clipYBut]).xHalf,
+ (control->buttonQueue[clipYBut]).buttonY,
+ (control->buttonQueue[clipYBut]).buttonX +
+ (control->buttonQueue[clipYBut]).xHalf,
+ (control->buttonQueue[clipYBut]).buttonY +
+ (control->buttonQueue[clipYBut]).buttonHeight,Xoption);
+ GDrawLine(trashGC,volumeWindow,
+ (control->buttonQueue[clipYBut]).buttonX +
+ (control->buttonQueue[clipYBut]).xHalf-3,
+ (control->buttonQueue[clipYBut]).buttonY-3,
+ (control->buttonQueue[clipYBut]).buttonX +
+ (control->buttonQueue[clipYBut]).xHalf,
+ (control->buttonQueue[clipYBut]).buttonY,Xoption);
+ GDrawLine(trashGC,volumeWindow,
+ (control->buttonQueue[clipYBut]).buttonX +
+ (control->buttonQueue[clipYBut]).xHalf+3,
+ (control->buttonQueue[clipYBut]).buttonY-3,
+ (control->buttonQueue[clipYBut]).buttonX +
+ (control->buttonQueue[clipYBut]).xHalf,
+ (control->buttonQueue[clipYBut]).buttonY,Xoption);
+ GDrawLine(trashGC,volumeWindow,
+ (control->buttonQueue[clipYBut]).buttonX +
+ (control->buttonQueue[clipYBut]).xHalf-3,
+ (control->buttonQueue[clipYBut]).buttonY +
+ (control->buttonQueue[clipYBut]).buttonHeight+3,
+ (control->buttonQueue[clipYBut]).buttonX +
+ (control->buttonQueue[clipYBut]).xHalf,
+ (control->buttonQueue[clipYBut]).buttonY +
+ (control->buttonQueue[clipYBut]).buttonHeight,Xoption);
+ GDrawLine(trashGC,volumeWindow,
+ (control->buttonQueue[clipYBut]).buttonX +
+ (control->buttonQueue[clipYBut]).xHalf+3,
+ (control->buttonQueue[clipYBut]).buttonY +
+ (control->buttonQueue[clipYBut]).buttonHeight+3,
+ (control->buttonQueue[clipYBut]).buttonX +
+ (control->buttonQueue[clipYBut]).xHalf,
+ (control->buttonQueue[clipYBut]).buttonY +
+ (control->buttonQueue[clipYBut]).buttonHeight,Xoption);
+
+ GSetForeground(trashGC,(float)monoColor(arcColor),Xoption);
+
+ /* note: minimum buttons closer to the box */
+ GFillArc(trashGC,volumeWindow,
+ (int)(clipYButX + minorAxis/2 - 8),
+ (int)(yClipMinN * (majorAxis-tinyArc) + clipYButY),
+ arcSize,arcSize,90*64,360*64,Xoption); /* 64 units per degree */
+ GFillArc(trashGC,volumeWindow,
+ (int)(clipYButX + minorAxis/2 + 3),
+ (int)(yClipMaxN * (majorAxis-tinyArc) + clipYButY),
+ arcSize,arcSize,90*64,360*64,Xoption); /* 64 units per degree */
+
+ GSetForeground(volumeGC,(float)monoColor(toggleColor),Xoption);
+ GDrawString(volumeGC,volumeWindow,clipYMessX,clipYMessY,"Y",1,Xoption);
+
+}
+
+
+void
+#ifdef _NO_PROTO
+drawClipZBut ()
+#else
+drawClipZBut (void)
+#endif
+{
+
+ XClearArea(dsply,volumeWindow,clipZButX,clipZButY,
+ midAxis+blank,midAxis+blank,False);
+ GSetForeground(trashGC,(float)monoColor(toggleColor),Xoption);
+ GDrawLine(trashGC,volumeWindow,clipZButTopEndX,clipZButTopEndY,
+ clipZButBotEndX,clipZButBotEndY,Xoption);
+ GDrawLine(trashGC,volumeWindow,clipZButTopEndX-4,clipZButTopEndY,
+ clipZButTopEndX,clipZButTopEndY,Xoption);
+
+ GDrawLine(trashGC,volumeWindow,clipZButTopEndX,clipZButTopEndY-4,
+ clipZButTopEndX,clipZButTopEndY,Xoption);
+
+ GDrawLine(trashGC,volumeWindow,clipZButBotEndX+4,clipZButBotEndY,
+ clipZButBotEndX,clipZButBotEndY,Xoption);
+
+ GDrawLine(trashGC,volumeWindow,clipZButBotEndX,clipZButBotEndY+4,
+ clipZButBotEndX,clipZButBotEndY,Xoption);
+
+
+ GSetForeground(trashGC,(float)monoColor(arcColor),Xoption);
+ GFillArc(trashGC,volumeWindow,
+ (int)(zClipMinN * midAxis * zFactor + clipZButTopEndX - 3),
+ (int)(zClipMinN * midAxis * zFactor + clipZButTopEndY + 3),
+ arcSize,arcSize,45*64,360*64,Xoption); /* 64 units per degree */
+ GFillArc(trashGC,volumeWindow,
+ (int)(zClipMaxN * midAxis * zFactor + clipZButTopEndX + 3),
+ (int)(zClipMaxN * midAxis * zFactor + clipZButTopEndY - 5),
+ arcSize,arcSize,45*64,360*64,Xoption); /* 64 units per degree */
+
+ GSetForeground(volumeGC,(float)monoColor(toggleColor),Xoption);
+ GDrawString(volumeGC,volumeWindow,clipZMessX,clipZMessY,"Z",1,Xoption);
+
+}
+
+
+void
+#ifdef _NO_PROTO
+drawClipVolume ()
+#else
+drawClipVolume (void)
+#endif
+{
+
+ float xminL,xmaxL,yminL,ymaxL,zminL,zmaxL;
+
+ XClearArea(dsply,volumeWindow,backFaceX-1,backFaceY,
+ lengthFace+deltaFace+2,lengthFace+deltaFace+1,False);
+
+ GSetForeground(trashGC,(float)boxInline,Xoption); /*boxOutline=133*/
+ GSetLineAttributes(trashGC,0,LineSolid,CapButt,JoinMiter,Xoption);
+
+ /* define corners of volume, clockwise, back to front */
+ xminL = xClipMinN*lengthFace;
+ xmaxL = xClipMaxN*lengthFace;
+ yminL = yClipMinN*lengthFace;
+ ymaxL = yClipMaxN*lengthFace;
+ zminL = zClipMinN*zLength;
+ zmaxL = (1-zClipMaxN)*zLength; /* percentage upwards from bottom */
+
+ flatClipBoxX[0] = backFaceX + xminL + zminL;
+ flatClipBoxY[0] = backFaceY + yminL + zminL;
+ flatClipBoxX[1] = backFaceX + xmaxL + zminL;
+ flatClipBoxY[1] = flatClipBoxY[0];
+ flatClipBoxX[2] = flatClipBoxX[1];
+ flatClipBoxY[2] = backFaceY + ymaxL + zminL;
+ flatClipBoxX[3] = flatClipBoxX[0];
+ flatClipBoxY[3] = flatClipBoxY[2];
+ flatClipBoxX[4] = frontFaceX + xminL - zmaxL;
+ flatClipBoxY[4] = frontFaceY + yminL - zmaxL;
+ flatClipBoxX[5] = frontFaceX + xmaxL - zmaxL;
+ flatClipBoxY[5] = flatClipBoxY[4];
+ flatClipBoxX[6] = flatClipBoxX[5];
+ flatClipBoxY[6] = frontFaceY + ymaxL - zmaxL;
+ flatClipBoxX[7] = flatClipBoxX[4];
+ flatClipBoxY[7] = flatClipBoxY[6];
+
+ /* now draw the volume */
+ GDrawRectangle(trashGC,volumeWindow,
+ flatClipBoxX[0],flatClipBoxY[0],
+ flatClipBoxX[2]-flatClipBoxX[0],
+ flatClipBoxY[2]-flatClipBoxY[0],Xoption);
+ GDrawLine(trashGC,volumeWindow,
+ flatClipBoxX[0],flatClipBoxY[0],flatClipBoxX[4],flatClipBoxY[4],Xoption);
+ GDrawLine(trashGC,volumeWindow,
+ flatClipBoxX[1],flatClipBoxY[1],flatClipBoxX[5],flatClipBoxY[5],Xoption);
+ GDrawLine(trashGC,volumeWindow,
+ flatClipBoxX[2],flatClipBoxY[2],flatClipBoxX[6],flatClipBoxY[6],Xoption);
+ GDrawLine(trashGC,volumeWindow,
+ flatClipBoxX[3],flatClipBoxY[3],flatClipBoxX[7],flatClipBoxY[7],Xoption);
+ GSetForeground(trashGC,(float)boxOutline,Xoption);
+ GDrawRectangle(trashGC,volumeWindow,
+ flatClipBoxX[4],flatClipBoxY[4],
+ flatClipBoxX[6]-flatClipBoxX[4],
+ flatClipBoxY[6]-flatClipBoxY[4],Xoption);
+ /* make sure volumeGC is set properly before calling these functions */
+
+} /* drawClipVolume() */
+
+
+void
+#ifdef _NO_PROTO
+drawHitherControl ()
+#else
+drawHitherControl (void)
+#endif
+{
+
+ float xx,b,slope;
+ int hitherTop, hitherBot;
+
+ float b0x,b1x;
+
+ /* draw box indicating minimum and maximum distance of projection */
+ GSetForeground(trashGC,(float)hitherBoxColor,Xoption);
+ b0x = (pzMin - clipPlaneMin)/(clipPlaneMax-clipPlaneMin);
+ b0x = hitherMaxX - b0x*(hitherMaxX - hitherMinX); /* screen x */
+ b1x = (pzMax - clipPlaneMin)/(clipPlaneMax-clipPlaneMin);
+ b1x = hitherMaxX - b1x*(hitherMaxX - hitherMinX); /* screen x */
+ GDraw3DButtonOut(trashGC,volumeWindow,
+ (int)(b0x),frusY(hitherBoxTop),
+ (int)fabs(b1x-b0x),hitherBoxHeight,Xoption);
+
+ /* draw the hither plane */
+ GSetForeground(trashGC,(float)hitherColor,Xoption);
+
+ /* percentage x */
+ xx = ((viewData.clipPlane-clipPlaneMin)/(clipPlaneMax-clipPlaneMin));
+ xx = hitherMaxX - xx*(hitherMaxX - hitherMinX); /* screen x */
+ slope = ((float)frustrumY - frustrumMidY)/(frustrumX - frustrumVertex);
+ b = ((float)frustrumX*frustrumMidY - frustrumVertex*frustrumY) /
+ (frustrumX - frustrumVertex);
+ hitherTop = slope * xx + b + 0.5;
+ slope = (float)(frustrumBotY - frustrumMidY)/(frustrumX - frustrumVertex);
+ b = ((float)frustrumX*frustrumMidY - frustrumVertex*frustrumBotY) /
+ (frustrumX - frustrumVertex);
+ hitherBot = slope * xx + b + 0.5;
+ GDrawLine(trashGC,volumeWindow, frusX((int)xx),frusY(hitherTop),
+ frusX((int)xx),frusY(hitherBot),Xoption);
+
+ /* draw hither control box and bar */
+ GDraw3DButtonOut(trashGC,volumeWindow,
+ frusX(hitherWinX),frusY(hitherWinY+5),
+ hitherWidth,hitherHeight,Xoption);
+ GDrawLine(trashGC,volumeWindow,
+ frusX(hitherMinX),frusY(hitherBarY+5),
+ frusX(hitherMaxX),frusY(hitherBarY+5),Xoption);
+ /* draw hither plane I/O pointer arrow */
+
+ GDrawLine(trashGC,volumeWindow,
+ frusX((int)xx),frusY(hitherBarY+2),
+ frusX((int)xx),frusY(hitherBarY+8),Xoption);
+
+ /* print string label */
+ GSetForeground(volumeGC,(float)hitherColor,Xoption);
+ GDrawString(volumeGC,volumeWindow,hitherMessX,hitherMessY,"Hither",6,Xoption);
+
+}
+
+void
+#ifdef _NO_PROTO
+drawEyeControl ()
+#else
+drawEyeControl (void)
+#endif
+{
+
+ float here;
+ int there;
+
+ GSetForeground(trashGC,(float)eyeColor,Xoption);
+
+ /* draw the eyeDistance box & slide bar */
+ GDraw3DButtonOut(trashGC,volumeWindow,
+ frusX(eyeWinX),frusY(eyeWinY+5),eyeWidth,eyeHeight,Xoption);
+ GDrawLine(trashGC,volumeWindow,
+ frusX(eyeMinX),frusY(eyeBarY+5),frusX(eyeMaxX),frusY(eyeBarY+5),Xoption);
+ here = (viewData.eyeDistance - minEyeDistance) /
+ (maxEyeDistance - minEyeDistance);
+ here = pow((double)here,0.333333);
+ there = here * (eyeMaxX - eyeMinX) + eyeMinX; /* screen x */
+ GDrawLine(trashGC,volumeWindow,
+ frusX(there),frusY(eyeBarY+2),frusX(there),frusY(eyeBarY+8),Xoption);
+
+ /* draw the eye */
+ GSetLineAttributes(trashGC,2,LineSolid,CapButt,JoinMiter,Xoption);
+ GSetForeground(trashGC,(float)monoColor(52),Xoption);
+ GDrawLine(trashGC,volumeWindow,
+ frusX(there),frusY(frustrumMidY-5),
+ frusX(there+8),frusY(frustrumMidY),Xoption);
+ GDrawLine(trashGC,volumeWindow,
+ frusX(there+2),frusY(frustrumMidY+4),
+ frusX(there+8),frusY(frustrumMidY-1),Xoption);
+ GSetForeground(trashGC,(float)frustrumColor,Xoption);
+ GDrawLine(trashGC,volumeWindow,
+ frusX(there+4),frusY(frustrumMidY-3),
+ frusX(there+2),frusY(frustrumMidY),Xoption);
+ GDrawLine(trashGC,volumeWindow,
+ frusX(there+4),frusY(frustrumMidY+2),
+ frusX(there+3),frusY(frustrumMidY),Xoption);
+ GSetLineAttributes(trashGC,0,LineSolid,CapButt,JoinMiter,Xoption);
+
+ /* draw string label */
+ GSetForeground(volumeGC,(float)eyeColor,Xoption);
+ GDrawString(volumeGC,volumeWindow,eyeDistMessX,eyeDistMessY,
+ "Eye Distance",strlen("eye distance"),Xoption);
+
+}
+
+
+/**************************
+ * void drawFrustrum() *
+ **************************/
+
+void
+#ifdef _NO_PROTO
+drawFrustrum ()
+#else
+drawFrustrum (void)
+#endif
+{
+
+ float normalizedEyeDistance;
+
+ XClearArea(dsply,volumeWindow,
+ control->buttonQueue[frustrumBut].buttonX,
+ control->buttonQueue[frustrumBut].buttonY,
+ control->buttonQueue[frustrumBut].buttonWidth+9,
+ control->buttonQueue[frustrumBut].buttonHeight,False);
+ GSetForeground(trashGC,(float)frustrumColor,Xoption);
+ normalizedEyeDistance = (viewData.eyeDistance - minEyeDistance) /
+ (maxEyeDistance - minEyeDistance);
+ normalizedEyeDistance = pow((double)normalizedEyeDistance,0.333333333);
+ frustrumVertex = normalizedEyeDistance * (frustrumMax - frustrumMin) +
+ frustrumMin - 4;
+ GDrawLine(trashGC,volumeWindow,
+ frusX(frustrumX),frusY(frustrumY),
+ frusX(frustrumX),frusY(frustrumY+frustrumLength),Xoption);
+ GDrawLine(trashGC,volumeWindow,
+ frusX(frustrumX),frusY(frustrumY),
+ frusX(frustrumVertex),frusY(frustrumMidY),Xoption);
+ GDrawLine(trashGC,volumeWindow,
+ frusX(frustrumX),frusY(frustrumBotY),
+ frusX(frustrumVertex),frusY(frustrumMidY),Xoption);
+
+ /* draw controls */
+ drawHitherControl();
+ drawEyeControl();
+
+} /* drawFrustrum() */
+
+
+
+/**************************
+ * void drawVolumePanel() *
+ **************************/
+
+void
+#ifdef _NO_PROTO
+drawVolumePanel ()
+#else
+drawVolumePanel (void)
+#endif
+{
+
+ int i,strlength;
+
+
+ /* Draw some lines for volume panel. */
+ GSetForeground(trashGC,(float)foregroundColor,Xoption);
+ GSetLineAttributes(trashGC,3,LineSolid,CapButt,JoinMiter,Xoption);
+ GDrawLine(trashGC, volumeWindow, 0, potA, controlWidth, potA, Xoption);
+
+ GSetLineAttributes(trashGC,2,LineSolid,CapButt,JoinMiter,Xoption);
+ GDrawLine(trashGC, volumeWindow, 0, volumeTitleA, controlWidth,
+ volumeTitleA, Xoption);
+ GDrawLine(trashGC, volumeWindow, 0, volumeTitleB, controlWidth,
+ volumeTitleB, Xoption);
+
+ writeControlTitle(volumeWindow);
+ s = "Viewing Volume Panel";
+ strlength = strlen(s);
+ GSetForeground(anotherGC,(float)volumeTitleColor,Xoption);
+ GDrawString(anotherGC,volumeWindow,
+ centerX(anotherGC,s,strlength,controlWidth),
+ volumeTitleA+18,s,strlength,Xoption);
+
+ GSetForeground(anotherGC,(float)monoColor(toggleColor),Xoption);
+ GDrawString(anotherGC,volumeWindow,
+ control->buttonQueue[perspectiveBut].buttonX + 4,
+ control->buttonQueue[perspectiveBut].buttonY - 17,
+ "Settings", 8, Xoption);
+
+ GSetForeground(trashGC,(float)monoColor(toggleColor),Xoption);
+ GDraw3DButtonOut(trashGC,volumeWindow,
+ control->buttonQueue[perspectiveBut].buttonX - 7,
+ control->buttonQueue[perspectiveBut].buttonY - 36,
+ 100,100,Xoption);
+
+
+ for (i=0; i<strlen(clipMess); i++)
+ GDrawString(trashGC,volumeWindow,clipMessX,clipMessY + i*clipMessDy,
+ &(clipMess[i]),1,Xoption);
+ for (i=0; i<strlen(eyeMess1); i++)
+ GDrawString(trashGC,volumeWindow,eyeMess1X,eyeMess1Y + i*eyeMess1Dy,
+ &(eyeMess1[i]),1,Xoption);
+ for (i=0; i<strlen(eyeMess2); i++)
+ GDrawString(trashGC,volumeWindow,eyeMess2X,eyeMess2Y + i*eyeMess2Dy,
+ &(eyeMess2[i]),1,Xoption);
+
+ GSetLineAttributes(trashGC,0,LineSolid,CapButt,JoinMiter,Xoption);
+ GSetForeground(trashGC,(float)volumeButtonColor,Xoption);
+ for (i=volumeButtonsStart; i<(volumeButtonsEnd); i++) {
+ GSetForeground(trashGC,
+ (float)monoColor((control->buttonQueue[i]).textColor),Xoption);
+ switch (i) {
+ case perspectiveBut:
+ case clipRegionBut:
+ case clipSurfaceBut:
+ GSetForeground(volumeGC,(float)monoColor(toggleColor),Xoption);
+ GDraw3DButtonOut(volumeGC,volumeWindow,
+ (control->buttonQueue[i]).buttonX,
+ (control->buttonQueue[i]).buttonY,
+ (control->buttonQueue[i]).buttonWidth,
+ (control->buttonQueue[i]).buttonHeight,Xoption);
+ GSetForeground(volumeGC,
+ (float)monoColor((control->buttonQueue[i]).textColor),Xoption);
+ GDrawString(volumeGC,volumeWindow,
+ (control->buttonQueue[i]).buttonX +
+ (control->buttonQueue[i]).buttonWidth + 4,
+ (control->buttonQueue[i]).buttonY +
+ centerY(volumeGC,(control->buttonQueue[i]).buttonHeight),
+ (control->buttonQueue[i]).text,
+ strlen(control->buttonQueue[i].text),Xoption);
+ if (i==perspectiveBut && viewData.perspective)
+ GDrawString(volumeGC,volumeWindow,
+ (control->buttonQueue[i]).buttonX +
+ centerX(volumeGC,"x",1,
+ (control->buttonQueue[i]).buttonWidth),
+ (control->buttonQueue[i]).buttonY +
+ centerY(volumeGC,(control->buttonQueue[i]).buttonHeight),
+ "x",1,Xoption);
+ else if (i==clipRegionBut && viewData.clipbox)
+ GDrawString(volumeGC,volumeWindow,
+ (control->buttonQueue[i]).buttonX +
+ centerX(volumeGC,"x",1,
+ (control->buttonQueue[i]).buttonWidth),
+ (control->buttonQueue[i]).buttonY +
+ centerY(volumeGC,(control->buttonQueue[i]).buttonHeight),
+ "x",1,Xoption);
+ else if (i==clipSurfaceBut && viewData.clipStuff)
+ GDrawString(volumeGC,volumeWindow,
+ (control->buttonQueue[i]).buttonX +
+ centerX(volumeGC,"x",1,
+ (control->buttonQueue[i]).buttonWidth),
+ (control->buttonQueue[i]).buttonY +
+ centerY(volumeGC,(control->buttonQueue[i]).buttonHeight),
+ "x",1,Xoption);
+
+ break;
+
+ case clipXBut:
+ drawClipXBut();
+ break;
+
+ case clipYBut:
+ drawClipYBut();
+ break;
+
+ case clipZBut:
+ drawClipZBut();
+ break;
+
+ case frustrumBut:
+ break;
+
+ default:
+ GDraw3DButtonOut(trashGC,volumeWindow,
+ (control->buttonQueue[i]).buttonX,
+ (control->buttonQueue[i]).buttonY,
+ (control->buttonQueue[i]).buttonWidth,
+ (control->buttonQueue[i]).buttonHeight,Xoption);
+ s = (control->buttonQueue[i]).text;
+ strlength = strlen(s);
+ GSetForeground(trashGC,
+ (float)monoColor((control->buttonQueue[i]).textColor),Xoption);
+ GDrawString(trashGC,volumeWindow,
+ (control->buttonQueue[i]).buttonX +
+ centerX(processGC,s,strlength,
+ (control->buttonQueue[i]).buttonWidth),
+ (control->buttonQueue[i]).buttonY +
+ centerY(processGC,(control->buttonQueue[i]).buttonHeight),
+ s,strlen(s),Xoption);
+ } /* switch */
+ } /* for i in volumeButtons */
+
+ drawFrustrum();
+ drawClipVolume(); /*** put in header ***/
+ drawClipXBut();
+ drawClipYBut();
+ drawClipZBut();
+
+} /* drawVolumePanel() */
+
+