/* Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd. All rights reserved. Copyright (C) 2007-2010, 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 "openaxiom-c-macros.h" #include #include #include "header.h" #include "cpanel.h" #include "process.h" #include "volume.h" #include "../include/purty/volume.bitmap" #include "../include/purty/volume.mask" #include "XSpadFill.h" #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 const char* clipMess = "Clip Volume"; #define eyeMess1Dy clipMessDy #define eyeMess1X 7 #define eyeMess1Y (frustrumY + 40 + 3*eyeMess1Dy) static const char* eyeMess1 = "Eye"; #define eyeMess2X (globalFont->max_bounds.width + 14) #define eyeMess2Y (frustrumY + 40) #define eyeMess2Dy eyeMess1Dy static const char* eyeMess2 = "Reference"; /* global stuff */ int flatClipBoxX[8], flatClipBoxY[8]; /******************* volume buttons **********************/ int initVolumeButtons (buttonStruct *volumeButtons) { 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 makeVolumePanel (void) { int i; XSetWindowAttributes cwAttrib, controlAttrib; XSizeHints sizehint; Pixmap volumebits, volumemask; XColor foreColor, backColor; volumebits = XCreateBitmapFromData(dsply,rtWindow, (const char*) volumeBitmap_bits, volumeBitmap_width,volumeBitmap_height); volumemask = XCreateBitmapFromData(dsply,rtWindow, (const char*) 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 drawClipXBut (void) { 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 drawClipYBut (void) { 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 drawClipZBut (void) { 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 drawClipVolume (void) { 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 drawHitherControl (void) { 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 drawEyeControl (void) { 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 drawFrustrum (void) { 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 drawVolumePanel (void) { size_t 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); strlength = strlen(clipMess); for (i=0; ibuttonQueue[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() */