open-axiom repository from github
/*1Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd.2All rights reserved.3Copyright (C) 2007-2010, Gabriel Dos Reis.4All rights reserved.56Redistribution and use in source and binary forms, with or without7modification, are permitted provided that the following conditions are8met:910- Redistributions of source code must retain the above copyright11notice, this list of conditions and the following disclaimer.1213- Redistributions in binary form must reproduce the above copyright14notice, this list of conditions and the following disclaimer in15the documentation and/or other materials provided with the16distribution.1718- Neither the name of The Numerical Algorithms Group Ltd. nor the19names of its contributors may be used to endorse or promote products20derived from this software without specific prior written permission.2122THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS23IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED24TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A25PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER26OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,27EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,28PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR29PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF30LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING31NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS32SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.33*/3435#define _VOLUME3D_C36#include "openaxiom-c-macros.h"3738#include <math.h>39#include <string.h>4041#include "header.h"42#include "cpanel.h"43#include "process.h"44#include "volume.h"45#include "../include/purty/volume.bitmap"46#include "../include/purty/volume.mask"47484950#include "XSpadFill.h"51#include "Gfun.H1"52#include "all_3d.H1"5354#define eyeDistMessX (frusX(eyeWinX+27))55#define eyeDistMessY (frusY(eyeWinY-5))56#define hitherMessX (frusX(hitherWinX+15))57#define hitherMessY (frusY(hitherWinY))5859#define clipXMessX (control->buttonQueue[clipXBut].buttonX + \60control->buttonQueue[clipXBut].xHalf)61#define clipXMessY (control->buttonQueue[clipXBut].buttonY + 2)62#define clipYMessX (control->buttonQueue[clipYBut].buttonX + \63control->buttonQueue[clipYBut].buttonWidth-2)64#define clipYMessY (control->buttonQueue[clipYBut].buttonY + \65control->buttonQueue[clipYBut].yHalf)66#define clipZMessX (control->buttonQueue[clipZBut].buttonX + \67control->buttonQueue[clipZBut].xHalf+4)68#define clipZMessY (control->buttonQueue[clipZBut].buttonY + \69control->buttonQueue[clipZBut].yHalf-4)7071#define volumeCursorForeground monoColor(68)72#define volumeCursorBackground monoColor(197)7374#define hitherBoxColor monoColor(141)75#define hitherBoxTop (frustrumMidY - 10)76#define hitherBoxHeight 207778#define clipButtonColor 14479#define toggleColor 4280#define arcColor 758182#define arcSize 683#define tinyArc 584#define blank 485#define toggleX 19086#define toggleY 2808788#define oldWay8990#define frusX(x) (control->buttonQueue[frustrumBut].buttonX + x)91#define frusY(y) (control->buttonQueue[frustrumBut].buttonY + y)9293#define clipMessX 794#define clipMessY (control->buttonQueue[clipXBut].buttonY + 15)95/* someotherFont holds title font (see main.c) */96#define clipMessDy (globalFont->max_bounds.ascent/2 + \97globalFont->max_bounds.descent)98static const char* clipMess = "Clip Volume";99100#define eyeMess1Dy clipMessDy101#define eyeMess1X 7102#define eyeMess1Y (frustrumY + 40 + 3*eyeMess1Dy)103static const char* eyeMess1 = "Eye";104105#define eyeMess2X (globalFont->max_bounds.width + 14)106#define eyeMess2Y (frustrumY + 40)107#define eyeMess2Dy eyeMess1Dy108static const char* eyeMess2 = "Reference";109110111/* global stuff */112int flatClipBoxX[8], flatClipBoxY[8];113114115116117/******************* volume buttons **********************/118119int120initVolumeButtons (buttonStruct *volumeButtons)121{122int ii, num = 0;123124ii = volumeReturn;125volumeButtons[ii].buttonX = 154;126volumeButtons[ii].buttonY = 370;127volumeButtons[ii].buttonWidth = 110;128volumeButtons[ii].buttonHeight = 24;129volumeButtons[ii].buttonKey = ii;130volumeButtons[ii].pot = no;131volumeButtons[ii].mask = buttonMASK;132volumeButtons[ii].text = "Return";133volumeButtons[ii].textColor = 52;134volumeButtons[ii].xHalf = volumeButtons[ii].buttonWidth/2;135volumeButtons[ii].yHalf = volumeButtons[ii].buttonHeight/2;136++num;137138ii = volumeAbort;139volumeButtons[ii].buttonX = 36;140volumeButtons[ii].buttonY = 370;141volumeButtons[ii].buttonWidth = 110;142volumeButtons[ii].buttonHeight = 24;143volumeButtons[ii].buttonKey = ii;144volumeButtons[ii].pot = no;145volumeButtons[ii].mask = buttonMASK;146volumeButtons[ii].text = "Abort";147volumeButtons[ii].textColor = 28;148volumeButtons[ii].xHalf = volumeButtons[ii].buttonWidth/2;149volumeButtons[ii].yHalf = volumeButtons[ii].buttonHeight/2;150++num;151152ii = frustrumBut;153volumeButtons[ii].buttonX = frustrumWindowX;154volumeButtons[ii].buttonY = frustrumWindowY;155volumeButtons[ii].buttonWidth = frustrumWindowWidth;156volumeButtons[ii].buttonHeight = frustrumWindowHeight;157volumeButtons[ii].buttonKey = ii;158volumeButtons[ii].pot = yes;159volumeButtons[ii].mask = potMASK;160volumeButtons[ii].text = "Frustrum Window";161volumeButtons[ii].textColor = frustrumColor;162volumeButtons[ii].xHalf = volumeButtons[ii].buttonWidth/2;163volumeButtons[ii].yHalf = volumeButtons[ii].buttonHeight/2;164++num;165166ii = perspectiveBut;167volumeButtons[ii].buttonX = toggleX;168volumeButtons[ii].buttonY = toggleY;169volumeButtons[ii].buttonWidth = 10;170volumeButtons[ii].buttonHeight = 10;171volumeButtons[ii].buttonKey = ii;172volumeButtons[ii].pot = no;173volumeButtons[ii].mask = potMASK;174volumeButtons[ii].text = "Perspective";175volumeButtons[ii].textColor = arcColor;176volumeButtons[ii].xHalf = volumeButtons[ii].buttonWidth/2;177volumeButtons[ii].yHalf = volumeButtons[ii].buttonHeight/2;178++num;179180ii = clipRegionBut;181volumeButtons[ii].buttonX = toggleX;182volumeButtons[ii].buttonY = toggleY+20;183volumeButtons[ii].buttonWidth = 10;184volumeButtons[ii].buttonHeight = 10;185volumeButtons[ii].buttonKey = ii;186volumeButtons[ii].pot = no;187volumeButtons[ii].mask = potMASK;188volumeButtons[ii].text = "Show Region";189volumeButtons[ii].textColor = arcColor;190volumeButtons[ii].xHalf = volumeButtons[ii].buttonWidth/2;191volumeButtons[ii].yHalf = volumeButtons[ii].buttonHeight/2;192++num;193194ii = clipSurfaceBut;195volumeButtons[ii].buttonX = toggleX;196volumeButtons[ii].buttonY = toggleY+40;197volumeButtons[ii].buttonWidth = 10;198volumeButtons[ii].buttonHeight = 10;199volumeButtons[ii].buttonKey = ii;200volumeButtons[ii].pot = no;201volumeButtons[ii].mask = potMASK;202volumeButtons[ii].text = "Clipping On";203volumeButtons[ii].textColor = arcColor;204volumeButtons[ii].xHalf = volumeButtons[ii].buttonWidth/2;205volumeButtons[ii].yHalf = volumeButtons[ii].buttonHeight/2;206++num;207208ii = clipXBut;209volumeButtons[ii].buttonX = clipXButX;210volumeButtons[ii].buttonY = clipXButY;211volumeButtons[ii].buttonWidth = majorAxis;212volumeButtons[ii].buttonHeight = minorAxis;213volumeButtons[ii].buttonKey = ii;214volumeButtons[ii].pot = yes;215volumeButtons[ii].mask = potMASK;216volumeButtons[ii].text = "Clip X";217volumeButtons[ii].textColor = clipButtonColor;218volumeButtons[ii].xHalf = volumeButtons[ii].buttonWidth/2;219volumeButtons[ii].yHalf = volumeButtons[ii].buttonHeight/2;220++num;221222ii = clipYBut;223volumeButtons[ii].buttonX = clipYButX;224volumeButtons[ii].buttonY = clipYButY;225volumeButtons[ii].buttonWidth = minorAxis;226volumeButtons[ii].buttonHeight = majorAxis;227volumeButtons[ii].buttonKey = ii;228volumeButtons[ii].pot = yes;229volumeButtons[ii].mask = potMASK;230volumeButtons[ii].text = "Clip Y";231volumeButtons[ii].textColor = clipButtonColor;232volumeButtons[ii].xHalf = volumeButtons[ii].buttonWidth/2;233volumeButtons[ii].yHalf = volumeButtons[ii].buttonHeight/2;234++num;235236ii = clipZBut;237volumeButtons[ii].buttonX = clipZButX;238volumeButtons[ii].buttonY = clipZButY;239volumeButtons[ii].buttonWidth = midAxis;240volumeButtons[ii].buttonHeight = midAxis;241volumeButtons[ii].buttonKey = ii;242volumeButtons[ii].pot = yes;243volumeButtons[ii].mask = potMASK;244volumeButtons[ii].text = "Clip Z";245volumeButtons[ii].textColor = clipButtonColor;246volumeButtons[ii].xHalf = volumeButtons[ii].buttonWidth/2;247volumeButtons[ii].yHalf = volumeButtons[ii].buttonHeight/2;248++num;249250return(num);251}252253254/*************************255* int makeVolumePanel() *256*************************/257258void259makeVolumePanel (void)260{261262int i;263XSetWindowAttributes cwAttrib, controlAttrib;264XSizeHints sizehint;265Pixmap volumebits, volumemask;266XColor foreColor, backColor;267268volumebits = XCreateBitmapFromData(dsply,rtWindow,269(const char*) volumeBitmap_bits,270volumeBitmap_width,volumeBitmap_height);271volumemask = XCreateBitmapFromData(dsply,rtWindow,272(const char*) volumeMask_bits,273volumeMask_width,volumeMask_height);274cwAttrib.background_pixel = backgroundColor;275cwAttrib.border_pixel = foregroundColor;276cwAttrib.event_mask = volumeMASK;277cwAttrib.colormap = colorMap;278cwAttrib.override_redirect = overrideManager;279foreColor.pixel = volumeCursorForeground;280XQueryColor(dsply,colorMap,&foreColor);281backColor.pixel = volumeCursorBackground;282XQueryColor(dsply,colorMap,&backColor);283cwAttrib.cursor = XCreatePixmapCursor(dsply,volumebits,volumemask,284&foreColor,&backColor,285volumeBitmap_x_hot,286volumeBitmap_y_hot);287volumeWindow = XCreateWindow(dsply,control->controlWindow,288-3,-3,controlWidth,controlHeight,3,289CopyFromParent,InputOutput,CopyFromParent,290controlCreateMASK,&cwAttrib);291292sizehint.flags = USPosition | USSize;293sizehint.x = 0;294sizehint.y = 0;295sizehint.width = controlWidth;296sizehint.height = controlHeight;297/*** the None stands for icon pixmap ***/298XSetNormalHints(dsply,volumeWindow,&sizehint);299XSetStandardProperties(dsply,volumeWindow,"Volume Panel 3D",300"View Volume",None,NULL,0,&sizehint);301302/*** volume frustrum window ***/303304/*** do volume buttons ***/305initVolumeButtons(control->buttonQueue);306for (i=volumeButtonsStart; i<(volumeButtonsEnd); i++) {307controlAttrib.event_mask = (control->buttonQueue[i]).mask;308(control->buttonQueue[i]).self =309XCreateWindow(dsply,volumeWindow,310(control->buttonQueue[i]).buttonX,311(control->buttonQueue[i]).buttonY,312(control->buttonQueue[i]).buttonWidth,313(control->buttonQueue[i]).buttonHeight,3140,0,InputOnly,CopyFromParent,315buttonCreateMASK,&controlAttrib);316XMakeAssoc(dsply,table,(control->buttonQueue[i]).self,317&((control->buttonQueue[i]).buttonKey));318XMapWindow(dsply,(control->buttonQueue[i]).self);319}320321} /* makeVolumePanel() */322323324void325drawClipXBut (void)326{327328XClearArea(dsply,volumeWindow,clipXButX,clipXButY,329majorAxis+blank,minorAxis+blank,False);330GSetForeground(trashGC,(float)monoColor(toggleColor),Xoption);331GDrawLine(trashGC,volumeWindow,332(control->buttonQueue[clipXBut]).buttonX,333(control->buttonQueue[clipXBut]).buttonY +334(control->buttonQueue[clipXBut]).yHalf,335(control->buttonQueue[clipXBut]).buttonX +336(control->buttonQueue[clipXBut]).buttonWidth,337(control->buttonQueue[clipXBut]).buttonY +338(control->buttonQueue[clipXBut]).yHalf,Xoption);339GDrawLine(trashGC,volumeWindow,340(control->buttonQueue[clipXBut]).buttonX-3,341(control->buttonQueue[clipXBut]).buttonY +342(control->buttonQueue[clipXBut]).yHalf-3,343(control->buttonQueue[clipXBut]).buttonX,344(control->buttonQueue[clipXBut]).buttonY +345(control->buttonQueue[clipXBut]).yHalf,Xoption);346GDrawLine(trashGC,volumeWindow,347(control->buttonQueue[clipXBut]).buttonX-3,348(control->buttonQueue[clipXBut]).buttonY +349(control->buttonQueue[clipXBut]).yHalf+3,350(control->buttonQueue[clipXBut]).buttonX,351(control->buttonQueue[clipXBut]).buttonY +352(control->buttonQueue[clipXBut]).yHalf,Xoption);353GDrawLine(trashGC,volumeWindow,354(control->buttonQueue[clipXBut]).buttonX +355(control->buttonQueue[clipXBut]).buttonWidth+3,356(control->buttonQueue[clipXBut]).buttonY +357(control->buttonQueue[clipXBut]).yHalf-3,358(control->buttonQueue[clipXBut]).buttonX +359(control->buttonQueue[clipXBut]).buttonWidth,360(control->buttonQueue[clipXBut]).buttonY +361(control->buttonQueue[clipXBut]).yHalf,Xoption);362GDrawLine(trashGC,volumeWindow,363(control->buttonQueue[clipXBut]).buttonX +364(control->buttonQueue[clipXBut]).buttonWidth+3,365(control->buttonQueue[clipXBut]).buttonY +366(control->buttonQueue[clipXBut]).yHalf+3,367(control->buttonQueue[clipXBut]).buttonX +368(control->buttonQueue[clipXBut]).buttonWidth,369(control->buttonQueue[clipXBut]).buttonY +370(control->buttonQueue[clipXBut]).yHalf,Xoption);371372GSetForeground(trashGC,(float)monoColor(arcColor),Xoption);373GFillArc(trashGC,volumeWindow,374(int)(xClipMinN * (majorAxis-tinyArc) + clipXButX), /* x value */375(int)(clipXButY + minorAxis/2 + 1), /* y value */376arcSize,arcSize,0,360*64,Xoption); /* 64 units per degree */377GFillArc(trashGC,volumeWindow,378(int)(xClipMaxN * (majorAxis-tinyArc) + clipXButX), /* x value */379(int)(clipXButY + minorAxis/2 - 7), /* y value */380arcSize,arcSize,0,360*64,Xoption); /* 64 units per degree */381382GSetForeground(volumeGC,(float)monoColor(toggleColor),Xoption);383GDrawString(volumeGC,volumeWindow,clipXMessX,clipXMessY,"X",1,Xoption);384385}386387void388drawClipYBut (void)389{390391XClearArea(dsply,volumeWindow,clipYButX,clipYButY,392minorAxis+blank,majorAxis+blank,False);393GSetForeground(trashGC,(float)monoColor(toggleColor),Xoption);394GDrawLine(trashGC,volumeWindow,395(control->buttonQueue[clipYBut]).buttonX +396(control->buttonQueue[clipYBut]).xHalf,397(control->buttonQueue[clipYBut]).buttonY,398(control->buttonQueue[clipYBut]).buttonX +399(control->buttonQueue[clipYBut]).xHalf,400(control->buttonQueue[clipYBut]).buttonY +401(control->buttonQueue[clipYBut]).buttonHeight,Xoption);402GDrawLine(trashGC,volumeWindow,403(control->buttonQueue[clipYBut]).buttonX +404(control->buttonQueue[clipYBut]).xHalf-3,405(control->buttonQueue[clipYBut]).buttonY-3,406(control->buttonQueue[clipYBut]).buttonX +407(control->buttonQueue[clipYBut]).xHalf,408(control->buttonQueue[clipYBut]).buttonY,Xoption);409GDrawLine(trashGC,volumeWindow,410(control->buttonQueue[clipYBut]).buttonX +411(control->buttonQueue[clipYBut]).xHalf+3,412(control->buttonQueue[clipYBut]).buttonY-3,413(control->buttonQueue[clipYBut]).buttonX +414(control->buttonQueue[clipYBut]).xHalf,415(control->buttonQueue[clipYBut]).buttonY,Xoption);416GDrawLine(trashGC,volumeWindow,417(control->buttonQueue[clipYBut]).buttonX +418(control->buttonQueue[clipYBut]).xHalf-3,419(control->buttonQueue[clipYBut]).buttonY +420(control->buttonQueue[clipYBut]).buttonHeight+3,421(control->buttonQueue[clipYBut]).buttonX +422(control->buttonQueue[clipYBut]).xHalf,423(control->buttonQueue[clipYBut]).buttonY +424(control->buttonQueue[clipYBut]).buttonHeight,Xoption);425GDrawLine(trashGC,volumeWindow,426(control->buttonQueue[clipYBut]).buttonX +427(control->buttonQueue[clipYBut]).xHalf+3,428(control->buttonQueue[clipYBut]).buttonY +429(control->buttonQueue[clipYBut]).buttonHeight+3,430(control->buttonQueue[clipYBut]).buttonX +431(control->buttonQueue[clipYBut]).xHalf,432(control->buttonQueue[clipYBut]).buttonY +433(control->buttonQueue[clipYBut]).buttonHeight,Xoption);434435GSetForeground(trashGC,(float)monoColor(arcColor),Xoption);436437/* note: minimum buttons closer to the box */438GFillArc(trashGC,volumeWindow,439(int)(clipYButX + minorAxis/2 - 8),440(int)(yClipMinN * (majorAxis-tinyArc) + clipYButY),441arcSize,arcSize,90*64,360*64,Xoption); /* 64 units per degree */442GFillArc(trashGC,volumeWindow,443(int)(clipYButX + minorAxis/2 + 3),444(int)(yClipMaxN * (majorAxis-tinyArc) + clipYButY),445arcSize,arcSize,90*64,360*64,Xoption); /* 64 units per degree */446447GSetForeground(volumeGC,(float)monoColor(toggleColor),Xoption);448GDrawString(volumeGC,volumeWindow,clipYMessX,clipYMessY,"Y",1,Xoption);449450}451452453void454drawClipZBut (void)455{456457XClearArea(dsply,volumeWindow,clipZButX,clipZButY,458midAxis+blank,midAxis+blank,False);459GSetForeground(trashGC,(float)monoColor(toggleColor),Xoption);460GDrawLine(trashGC,volumeWindow,clipZButTopEndX,clipZButTopEndY,461clipZButBotEndX,clipZButBotEndY,Xoption);462GDrawLine(trashGC,volumeWindow,clipZButTopEndX-4,clipZButTopEndY,463clipZButTopEndX,clipZButTopEndY,Xoption);464465GDrawLine(trashGC,volumeWindow,clipZButTopEndX,clipZButTopEndY-4,466clipZButTopEndX,clipZButTopEndY,Xoption);467468GDrawLine(trashGC,volumeWindow,clipZButBotEndX+4,clipZButBotEndY,469clipZButBotEndX,clipZButBotEndY,Xoption);470471GDrawLine(trashGC,volumeWindow,clipZButBotEndX,clipZButBotEndY+4,472clipZButBotEndX,clipZButBotEndY,Xoption);473474475GSetForeground(trashGC,(float)monoColor(arcColor),Xoption);476GFillArc(trashGC,volumeWindow,477(int)(zClipMinN * midAxis * zFactor + clipZButTopEndX - 3),478(int)(zClipMinN * midAxis * zFactor + clipZButTopEndY + 3),479arcSize,arcSize,45*64,360*64,Xoption); /* 64 units per degree */480GFillArc(trashGC,volumeWindow,481(int)(zClipMaxN * midAxis * zFactor + clipZButTopEndX + 3),482(int)(zClipMaxN * midAxis * zFactor + clipZButTopEndY - 5),483arcSize,arcSize,45*64,360*64,Xoption); /* 64 units per degree */484485GSetForeground(volumeGC,(float)monoColor(toggleColor),Xoption);486GDrawString(volumeGC,volumeWindow,clipZMessX,clipZMessY,"Z",1,Xoption);487488}489490491void492drawClipVolume (void)493{494495float xminL,xmaxL,yminL,ymaxL,zminL,zmaxL;496497XClearArea(dsply,volumeWindow,backFaceX-1,backFaceY,498lengthFace+deltaFace+2,lengthFace+deltaFace+1,False);499500GSetForeground(trashGC,(float)boxInline,Xoption); /*boxOutline=133*/501GSetLineAttributes(trashGC,0,LineSolid,CapButt,JoinMiter,Xoption);502503/* define corners of volume, clockwise, back to front */504xminL = xClipMinN*lengthFace;505xmaxL = xClipMaxN*lengthFace;506yminL = yClipMinN*lengthFace;507ymaxL = yClipMaxN*lengthFace;508zminL = zClipMinN*zLength;509zmaxL = (1-zClipMaxN)*zLength; /* percentage upwards from bottom */510511flatClipBoxX[0] = backFaceX + xminL + zminL;512flatClipBoxY[0] = backFaceY + yminL + zminL;513flatClipBoxX[1] = backFaceX + xmaxL + zminL;514flatClipBoxY[1] = flatClipBoxY[0];515flatClipBoxX[2] = flatClipBoxX[1];516flatClipBoxY[2] = backFaceY + ymaxL + zminL;517flatClipBoxX[3] = flatClipBoxX[0];518flatClipBoxY[3] = flatClipBoxY[2];519flatClipBoxX[4] = frontFaceX + xminL - zmaxL;520flatClipBoxY[4] = frontFaceY + yminL - zmaxL;521flatClipBoxX[5] = frontFaceX + xmaxL - zmaxL;522flatClipBoxY[5] = flatClipBoxY[4];523flatClipBoxX[6] = flatClipBoxX[5];524flatClipBoxY[6] = frontFaceY + ymaxL - zmaxL;525flatClipBoxX[7] = flatClipBoxX[4];526flatClipBoxY[7] = flatClipBoxY[6];527528/* now draw the volume */529GDrawRectangle(trashGC,volumeWindow,530flatClipBoxX[0],flatClipBoxY[0],531flatClipBoxX[2]-flatClipBoxX[0],532flatClipBoxY[2]-flatClipBoxY[0],Xoption);533GDrawLine(trashGC,volumeWindow,534flatClipBoxX[0],flatClipBoxY[0],flatClipBoxX[4],flatClipBoxY[4],Xoption);535GDrawLine(trashGC,volumeWindow,536flatClipBoxX[1],flatClipBoxY[1],flatClipBoxX[5],flatClipBoxY[5],Xoption);537GDrawLine(trashGC,volumeWindow,538flatClipBoxX[2],flatClipBoxY[2],flatClipBoxX[6],flatClipBoxY[6],Xoption);539GDrawLine(trashGC,volumeWindow,540flatClipBoxX[3],flatClipBoxY[3],flatClipBoxX[7],flatClipBoxY[7],Xoption);541GSetForeground(trashGC,(float)boxOutline,Xoption);542GDrawRectangle(trashGC,volumeWindow,543flatClipBoxX[4],flatClipBoxY[4],544flatClipBoxX[6]-flatClipBoxX[4],545flatClipBoxY[6]-flatClipBoxY[4],Xoption);546/* make sure volumeGC is set properly before calling these functions */547548} /* drawClipVolume() */549550551void552drawHitherControl (void)553{554555float xx,b,slope;556int hitherTop, hitherBot;557558float b0x,b1x;559560/* draw box indicating minimum and maximum distance of projection */561GSetForeground(trashGC,(float)hitherBoxColor,Xoption);562b0x = (pzMin - clipPlaneMin)/(clipPlaneMax-clipPlaneMin);563b0x = hitherMaxX - b0x*(hitherMaxX - hitherMinX); /* screen x */564b1x = (pzMax - clipPlaneMin)/(clipPlaneMax-clipPlaneMin);565b1x = hitherMaxX - b1x*(hitherMaxX - hitherMinX); /* screen x */566GDraw3DButtonOut(trashGC,volumeWindow,567(int)(b0x),frusY(hitherBoxTop),568(int)fabs(b1x-b0x),hitherBoxHeight,Xoption);569570/* draw the hither plane */571GSetForeground(trashGC,(float)hitherColor,Xoption);572573/* percentage x */574xx = ((viewData.clipPlane-clipPlaneMin)/(clipPlaneMax-clipPlaneMin));575xx = hitherMaxX - xx*(hitherMaxX - hitherMinX); /* screen x */576slope = ((float)frustrumY - frustrumMidY)/(frustrumX - frustrumVertex);577b = ((float)frustrumX*frustrumMidY - frustrumVertex*frustrumY) /578(frustrumX - frustrumVertex);579hitherTop = slope * xx + b + 0.5;580slope = (float)(frustrumBotY - frustrumMidY)/(frustrumX - frustrumVertex);581b = ((float)frustrumX*frustrumMidY - frustrumVertex*frustrumBotY) /582(frustrumX - frustrumVertex);583hitherBot = slope * xx + b + 0.5;584GDrawLine(trashGC,volumeWindow, frusX((int)xx),frusY(hitherTop),585frusX((int)xx),frusY(hitherBot),Xoption);586587/* draw hither control box and bar */588GDraw3DButtonOut(trashGC,volumeWindow,589frusX(hitherWinX),frusY(hitherWinY+5),590hitherWidth,hitherHeight,Xoption);591GDrawLine(trashGC,volumeWindow,592frusX(hitherMinX),frusY(hitherBarY+5),593frusX(hitherMaxX),frusY(hitherBarY+5),Xoption);594/* draw hither plane I/O pointer arrow */595596GDrawLine(trashGC,volumeWindow,597frusX((int)xx),frusY(hitherBarY+2),598frusX((int)xx),frusY(hitherBarY+8),Xoption);599600/* print string label */601GSetForeground(volumeGC,(float)hitherColor,Xoption);602GDrawString(volumeGC,volumeWindow,hitherMessX,hitherMessY,"Hither",6,Xoption);603604}605606void607drawEyeControl (void)608{609610float here;611int there;612613GSetForeground(trashGC,(float)eyeColor,Xoption);614615/* draw the eyeDistance box & slide bar */616GDraw3DButtonOut(trashGC,volumeWindow,617frusX(eyeWinX),frusY(eyeWinY+5),eyeWidth,eyeHeight,Xoption);618GDrawLine(trashGC,volumeWindow,619frusX(eyeMinX),frusY(eyeBarY+5),frusX(eyeMaxX),frusY(eyeBarY+5),Xoption);620here = (viewData.eyeDistance - minEyeDistance) /621(maxEyeDistance - minEyeDistance);622here = pow((double)here,0.333333);623there = here * (eyeMaxX - eyeMinX) + eyeMinX; /* screen x */624GDrawLine(trashGC,volumeWindow,625frusX(there),frusY(eyeBarY+2),frusX(there),frusY(eyeBarY+8),Xoption);626627/* draw the eye */628GSetLineAttributes(trashGC,2,LineSolid,CapButt,JoinMiter,Xoption);629GSetForeground(trashGC,(float)monoColor(52),Xoption);630GDrawLine(trashGC,volumeWindow,631frusX(there),frusY(frustrumMidY-5),632frusX(there+8),frusY(frustrumMidY),Xoption);633GDrawLine(trashGC,volumeWindow,634frusX(there+2),frusY(frustrumMidY+4),635frusX(there+8),frusY(frustrumMidY-1),Xoption);636GSetForeground(trashGC,(float)frustrumColor,Xoption);637GDrawLine(trashGC,volumeWindow,638frusX(there+4),frusY(frustrumMidY-3),639frusX(there+2),frusY(frustrumMidY),Xoption);640GDrawLine(trashGC,volumeWindow,641frusX(there+4),frusY(frustrumMidY+2),642frusX(there+3),frusY(frustrumMidY),Xoption);643GSetLineAttributes(trashGC,0,LineSolid,CapButt,JoinMiter,Xoption);644645/* draw string label */646GSetForeground(volumeGC,(float)eyeColor,Xoption);647GDrawString(volumeGC,volumeWindow,eyeDistMessX,eyeDistMessY,648"Eye Distance",strlen("eye distance"),Xoption);649650}651652653/**************************654* void drawFrustrum() *655**************************/656657void658drawFrustrum (void)659{660661float normalizedEyeDistance;662663XClearArea(dsply,volumeWindow,664control->buttonQueue[frustrumBut].buttonX,665control->buttonQueue[frustrumBut].buttonY,666control->buttonQueue[frustrumBut].buttonWidth+9,667control->buttonQueue[frustrumBut].buttonHeight,False);668GSetForeground(trashGC,(float)frustrumColor,Xoption);669normalizedEyeDistance = (viewData.eyeDistance - minEyeDistance) /670(maxEyeDistance - minEyeDistance);671normalizedEyeDistance = pow((double)normalizedEyeDistance,0.333333333);672frustrumVertex = normalizedEyeDistance * (frustrumMax - frustrumMin) +673frustrumMin - 4;674GDrawLine(trashGC,volumeWindow,675frusX(frustrumX),frusY(frustrumY),676frusX(frustrumX),frusY(frustrumY+frustrumLength),Xoption);677GDrawLine(trashGC,volumeWindow,678frusX(frustrumX),frusY(frustrumY),679frusX(frustrumVertex),frusY(frustrumMidY),Xoption);680GDrawLine(trashGC,volumeWindow,681frusX(frustrumX),frusY(frustrumBotY),682frusX(frustrumVertex),frusY(frustrumMidY),Xoption);683684/* draw controls */685drawHitherControl();686drawEyeControl();687688} /* drawFrustrum() */689690691692/**************************693* void drawVolumePanel() *694**************************/695696void697drawVolumePanel (void)698{699700int i,strlength;701702703/* Draw some lines for volume panel. */704GSetForeground(trashGC,(float)foregroundColor,Xoption);705GSetLineAttributes(trashGC,3,LineSolid,CapButt,JoinMiter,Xoption);706GDrawLine(trashGC, volumeWindow, 0, potA, controlWidth, potA, Xoption);707708GSetLineAttributes(trashGC,2,LineSolid,CapButt,JoinMiter,Xoption);709GDrawLine(trashGC, volumeWindow, 0, volumeTitleA, controlWidth,710volumeTitleA, Xoption);711GDrawLine(trashGC, volumeWindow, 0, volumeTitleB, controlWidth,712volumeTitleB, Xoption);713714writeControlTitle(volumeWindow);715s = "Viewing Volume Panel";716strlength = strlen(s);717GSetForeground(anotherGC,(float)volumeTitleColor,Xoption);718GDrawString(anotherGC,volumeWindow,719centerX(anotherGC,s,strlength,controlWidth),720volumeTitleA+18,s,strlength,Xoption);721722GSetForeground(anotherGC,(float)monoColor(toggleColor),Xoption);723GDrawString(anotherGC,volumeWindow,724control->buttonQueue[perspectiveBut].buttonX + 4,725control->buttonQueue[perspectiveBut].buttonY - 17,726"Settings", 8, Xoption);727728GSetForeground(trashGC,(float)monoColor(toggleColor),Xoption);729GDraw3DButtonOut(trashGC,volumeWindow,730control->buttonQueue[perspectiveBut].buttonX - 7,731control->buttonQueue[perspectiveBut].buttonY - 36,732100,100,Xoption);733734735for (i=0; i<strlen(clipMess); i++)736GDrawString(trashGC,volumeWindow,clipMessX,clipMessY + i*clipMessDy,737&(clipMess[i]),1,Xoption);738for (i=0; i<strlen(eyeMess1); i++)739GDrawString(trashGC,volumeWindow,eyeMess1X,eyeMess1Y + i*eyeMess1Dy,740&(eyeMess1[i]),1,Xoption);741for (i=0; i<strlen(eyeMess2); i++)742GDrawString(trashGC,volumeWindow,eyeMess2X,eyeMess2Y + i*eyeMess2Dy,743&(eyeMess2[i]),1,Xoption);744745GSetLineAttributes(trashGC,0,LineSolid,CapButt,JoinMiter,Xoption);746GSetForeground(trashGC,(float)volumeButtonColor,Xoption);747for (i=volumeButtonsStart; i<(volumeButtonsEnd); i++) {748GSetForeground(trashGC,749(float)monoColor((control->buttonQueue[i]).textColor),Xoption);750switch (i) {751case perspectiveBut:752case clipRegionBut:753case clipSurfaceBut:754GSetForeground(volumeGC,(float)monoColor(toggleColor),Xoption);755GDraw3DButtonOut(volumeGC,volumeWindow,756(control->buttonQueue[i]).buttonX,757(control->buttonQueue[i]).buttonY,758(control->buttonQueue[i]).buttonWidth,759(control->buttonQueue[i]).buttonHeight,Xoption);760GSetForeground(volumeGC,761(float)monoColor((control->buttonQueue[i]).textColor),Xoption);762GDrawString(volumeGC,volumeWindow,763(control->buttonQueue[i]).buttonX +764(control->buttonQueue[i]).buttonWidth + 4,765(control->buttonQueue[i]).buttonY +766centerY(volumeGC,(control->buttonQueue[i]).buttonHeight),767(control->buttonQueue[i]).text,768strlen(control->buttonQueue[i].text),Xoption);769if (i==perspectiveBut && viewData.perspective)770GDrawString(volumeGC,volumeWindow,771(control->buttonQueue[i]).buttonX +772centerX(volumeGC,"x",1,773(control->buttonQueue[i]).buttonWidth),774(control->buttonQueue[i]).buttonY +775centerY(volumeGC,(control->buttonQueue[i]).buttonHeight),776"x",1,Xoption);777else if (i==clipRegionBut && viewData.clipbox)778GDrawString(volumeGC,volumeWindow,779(control->buttonQueue[i]).buttonX +780centerX(volumeGC,"x",1,781(control->buttonQueue[i]).buttonWidth),782(control->buttonQueue[i]).buttonY +783centerY(volumeGC,(control->buttonQueue[i]).buttonHeight),784"x",1,Xoption);785else if (i==clipSurfaceBut && viewData.clipStuff)786GDrawString(volumeGC,volumeWindow,787(control->buttonQueue[i]).buttonX +788centerX(volumeGC,"x",1,789(control->buttonQueue[i]).buttonWidth),790(control->buttonQueue[i]).buttonY +791centerY(volumeGC,(control->buttonQueue[i]).buttonHeight),792"x",1,Xoption);793794break;795796case clipXBut:797drawClipXBut();798break;799800case clipYBut:801drawClipYBut();802break;803804case clipZBut:805drawClipZBut();806break;807808case frustrumBut:809break;810811default:812GDraw3DButtonOut(trashGC,volumeWindow,813(control->buttonQueue[i]).buttonX,814(control->buttonQueue[i]).buttonY,815(control->buttonQueue[i]).buttonWidth,816(control->buttonQueue[i]).buttonHeight,Xoption);817s = (control->buttonQueue[i]).text;818strlength = strlen(s);819GSetForeground(trashGC,820(float)monoColor((control->buttonQueue[i]).textColor),Xoption);821GDrawString(trashGC,volumeWindow,822(control->buttonQueue[i]).buttonX +823centerX(processGC,s,strlength,824(control->buttonQueue[i]).buttonWidth),825(control->buttonQueue[i]).buttonY +826centerY(processGC,(control->buttonQueue[i]).buttonHeight),827s,strlen(s),Xoption);828} /* switch */829} /* for i in volumeButtons */830831drawFrustrum();832drawClipVolume(); /*** put in header ***/833drawClipXBut();834drawClipYBut();835drawClipZBut();836837} /* drawVolumePanel() */838839840841842