SurfaceToolImpl.mesa
James Rauen, July 3, 1986 10:27:31 pm PDT
July 14, 1986 5:20:47 pm PDT
Last edited by: James Rauen January 21, 1988 6:47:44 pm PST
DIRECTORY
Buttons USING [Button, ButtonProc, Create, SetDisplayStyle],
CADIO USING [Error, ReadInfoFile, ReadVAXCadFiles, SelectCell, WriteInfoFile],
CADTypes USING [Scad, VisibleMask],
Commander USING [CommandProc, Register],
Containers USING [ChildXBound, Container, Create],
Convert USING [Error, RealFromRope, RopeFromInt],
Geometry3dMatrix USING [MakePureRotate, Matrix, Transform],
Geometry3dVector USING [Add, Cross, Mul, Negate, Normalize, Ortho, Sub, Triple],
ImagerColor USING [RGB],
IO USING [real, PutFR],
Labels USING [Create, Label, Set],
Menus USING [AppendMenuEntry, CreateEntry, CreateMenu, Menu, MenuEntry, MenuProc],
MessageWindow USING [Append, Blink],
MultiPolynomial USING [RopeFromRef],
PopUpSelection USING [Request],
Real USING [InlineFix],
Rope USING [Cat, Concat, ROPE],
Rules USING [Create, Rule],
SurfaceIcons USING [SurfaceToolIcon],
SurfaceTool,
SurfaceViewer,
ThreeDBasics USING [Context, SetView],
UserProfile USING [Number, Token],
VFonts USING [CharWidth, EstablishFont, StringWidth],
ViewerClasses USING [Viewer],
ViewerOps USING [OpenIcon],
ViewerSpecs USING [openLeftWidth],
ViewerTools USING [GetContents, GetSelectionContents, MakeNewTextViewer, SetContents, SetSelection];
SurfaceToolImpl: CEDAR PROGRAM
IMPORTS Buttons, CADIO, Commander, Containers, Convert, IO, Labels, Geometry3dMatrix, Menus, MessageWindow, MultiPolynomial, PopUpSelection, Real, Rope, Rules, SurfaceViewer, ThreeDBasics, UserProfile, Geometry3dVector, VFonts, ViewerOps, ViewerSpecs, ViewerTools
EXPORTS SurfaceTool
~ BEGIN
Type declarations
SurfaceToolRef: TYPE ~ REF SurfaceToolRec;
SurfaceToolRec: TYPE ~ RECORD [
outer: Containers.Container ← NIL,
height: CARDINAL ← 0,
buttonsLocked: BOOLEANFALSE,
sviewer: REF SurfaceViewer.SurfaceViewer,
positionAndOrientationState: PositionAndOrientationState,
activeState: ActiveState,
interpressState: InterpressState,
conversionState: ConversionState];
MakeSurfaceTool: PUBLIC PROC[sviewer: REF SurfaceViewer.SurfaceViewer] ~ BEGIN
Declarations
surfaceTool: SurfaceToolRef ← NEW[SurfaceToolRec];
topMenu: Menus.Menu;
viewEntry, breakEntry: Menus.MenuEntry;
Build the top menu
topMenu ← Menus.CreateMenu[];
viewEntry ← Menus.CreateEntry["View", BugView, surfaceTool];
breakEntry ← Menus.CreateEntry["Break", BugBreak, surfaceTool];
Menus.AppendMenuEntry[topMenu, viewEntry];
Menus.AppendMenuEntry[topMenu, breakEntry];
Menus.SetGuarded [openEntry, TRUE];
Create the tool
surfaceTool.outer ← Containers.Create[[
name: "Algebraic Surface Tool",
icon: SurfaceIcons.SurfaceToolIcon[],
iconic: TRUE,
column: left,
menu: topMenu,
scrollable: FALSE]];
surfaceTool.sviewer ← sviewer;
Add the subviewers
BuildPositionSubviewer[surfaceTool];
BuildActiveSubviewer[surfaceTool];
BuildInterpressSubviewer[surfaceTool];
BuildRayTracerSubviewer[surfaceTool];
BuildConversionSubviewer[surfaceTool];
Add edges on the left and right -- so the viewer looks nice when turned into an IP file.
[] ← Rules.Create [[wx: 0, wy: 0, ww: 1, wh: surfaceTool.height, parent: surfaceTool.outer]];
[] ← Rules.Create [[wx: (toolWidth - 1), wy: 0, ww: 1, wh: surfaceTool.height, parent: surfaceTool.outer]];
Open it
ViewerOps.OpenIcon[icon: surfaceTool.outer, closeOthers: TRUE, bottom: FALSE];
ViewerOps.PaintViewer[surfaceTool.outer, all];
END;
SurfaceTool button procedures
BugView: Menus.MenuProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
MakeNewFrame[surfaceTool];
END;
BugBreak: Menus.MenuProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
context3d: REF ThreeDBasics.Context ← surfaceTool.sviewer.context3d;
SIGNAL SurfaceToolBreak;
END;
SurfaceToolBreak: SIGNAL = CODE;
MakeNewFrame: PROC[surfaceTool: SurfaceToolRef] ~ BEGIN
Updates everything in the SurfaceViewer context, then draws a frame.
ThreeDBasics.SetView [
context:  SurfaceViewer.GetThreeDContext[surfaceTool.sviewer],
eyePoint:  surfaceTool.positionAndOrientationState.position,
ptOfInterest: Geometry3dVector.Add[surfaceTool.positionAndOrientationState.position, surfaceTool.positionAndOrientationState.forward],
upDirection: surfaceTool.positionAndOrientationState.up];
SurfaceViewer.DrawFrame[surfaceTool.sviewer];
END;
Window formatting constants
smallHorizontalSpacing: CARDINAL ~ 10;
largeHorizontalSpacing: CARDINAL ~ 20;
smallVerticalSpacing: CARDINAL ~ 8;
largeVerticalSpacing: CARDINAL ~ 16;
smallButtonWidth: CARDINAL ~ 3 * VFonts.CharWidth['+];
dataButtonWidth: CARDINAL ~ 5 * VFonts.CharWidth['=];
dataViewerWidth: CARDINAL ~ 6*VFonts.CharWidth['0];
fileViewerWidth: CARDINAL ~ 30*VFonts.CharWidth['N];
verticalHeight: CARDINAL ~ 15;
textViewerHeight: CARDINAL ~ verticalHeight + 6;
toolWidth: CARDINAL ~ ViewerSpecs.openLeftWidth;
verticalSpacingAboveSubviewer: CARDINAL ~ 1;
verticalSpacingBelowSubviewer: CARDINAL ~ 1;
Conversion subviewer
ConversionState: TYPE ~ RECORD [
sourceDir: ViewerClasses.Viewer ← NIL,
cadFile: ViewerClasses.Viewer ← NIL,
csFile: ViewerClasses.Viewer ← NIL,
destDir: ViewerClasses.Viewer ← NIL,
destFile: ViewerClasses.Viewer ← NIL
];
BuildConversionSubviewer: PROC [surfaceTool: SurfaceToolRef] ~ BEGIN
Formatting constants.
baseX: CARDINAL ~ 5;
baseY: CARDINAL ~ surfaceTool.height + verticalSpacingAboveSubviewer;
topRow: CARDINAL ~ baseY;
subRow: CARDINAL ~ topRow + verticalHeight;
firstRow: CARDINAL ~ subRow + smallVerticalSpacing;
secondRow: CARDINAL ~ firstRow + verticalHeight + smallVerticalSpacing;
thirdRow: CARDINAL ~ secondRow + verticalHeight + smallVerticalSpacing;
fourthRow: CARDINAL ~ thirdRow + verticalHeight + smallVerticalSpacing;
bottomRow: CARDINAL ~ fourthRow + verticalHeight + smallVerticalSpacing;
buttonWidth: CARDINAL ~ VFonts.StringWidth[" Do It "];
viewerWidth: CARDINAL ~ (toolWidth/2) - baseX - buttonWidth;
sourceButtonColumn: CARDINAL ~ baseX;
sourceViewerColumn: CARDINAL ~ sourceButtonColumn + buttonWidth;
destButtonColumn: CARDINAL ~ toolWidth / 2;
destViewerColumn: CARDINAL ~ destButtonColumn + buttonWidth;
doItColumn: CARDINAL ~ toolWidth * 3 / 4;
title: Rope.ROPE ~ "File Conversion";
titleColumn: CARDINAL ~ (toolWidth - VFonts.StringWidth[title])/2;
Declare the rules that will be built.
hrule1, hrule2, hrule3: Rules.Rule;
Build the title.
[] ← BuildLabel [title, surfaceTool.outer, titleColumn, topRow, TRUE];
Build the labels.
[] ← BuildLabel ["Source files (CAD and Covering Set)", surfaceTool.outer, sourceButtonColumn, firstRow];
[] ← BuildLabel ["Destination file (Algebraic surface)", surfaceTool.outer, destButtonColumn, firstRow];
Build the buttons.
[] ← BuildButton [surfaceTool, "Dir:", sourceButtonColumn, secondRow, BugSourceDir, TRUE, buttonWidth];
[] ← BuildButton [surfaceTool, "CAD:", sourceButtonColumn, thirdRow, BugCadFile, TRUE, buttonWidth];
[] ← BuildButton [surfaceTool, "CS:", sourceButtonColumn, fourthRow, BugCSFile, TRUE, buttonWidth];
[] ← BuildButton [surfaceTool, "Dir:", destButtonColumn, secondRow, BugDestDir, TRUE, buttonWidth];
[] ← BuildButton [surfaceTool, "File:", destButtonColumn, thirdRow, BugDestFile, TRUE, buttonWidth];
[] ← BuildButton [surfaceTool, "Do It", doItColumn, fourthRow, BugConvert, TRUE, buttonWidth];
Build the text viewers.
surfaceTool.conversionState.sourceDir ← BuildTextViewer [surfaceTool.outer, sourceViewerColumn, secondRow, viewerWidth];
surfaceTool.conversionState.cadFile ← BuildTextViewer [surfaceTool.outer, sourceViewerColumn, thirdRow, viewerWidth];
surfaceTool.conversionState.csFile ← BuildTextViewer [surfaceTool.outer, sourceViewerColumn, fourthRow, viewerWidth];
surfaceTool.conversionState.destDir ← BuildTextViewer [surfaceTool.outer, destViewerColumn, secondRow, viewerWidth];
surfaceTool.conversionState.destFile ← BuildTextViewer [surfaceTool.outer, destViewerColumn, thirdRow, viewerWidth];
Fill in their defaults from the user profile.
ViewerTools.SetContents[surfaceTool.conversionState.sourceDir, UserProfile.Token["AlgebraicSurfaces.Directory"]];
ViewerTools.SetContents[surfaceTool.conversionState.destDir, UserProfile.Token["AlgebraicSurfaces.Directory"]];
Draw the horizontal lines and constrain them to be the width of the tool.
hrule1 ← Rules.Create [[wx: 0, wy: topRow, wh: 1, parent: surfaceTool.outer]];
hrule2 ← Rules.Create [[wx: 0, wy: subRow, wh: 1, parent: surfaceTool.outer]];
hrule3 ← Rules.Create [[wx: 0, wy: bottomRow, wh: 1, parent: surfaceTool.outer]];
Containers.ChildXBound[surfaceTool.outer, hrule1];
Containers.ChildXBound[surfaceTool.outer, hrule2];
Containers.ChildXBound[surfaceTool.outer, hrule3];
Extend the tool's height.
surfaceTool.height ← surfaceTool.height + bottomRow - baseY + 1 + verticalSpacingBelowSubviewer;
END;
Conversion subviewer button procedures
BugSourceDir: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
ViewerTools.SetSelection[surfaceTool.conversionState.sourceDir];
END;
BugCadFile: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
ViewerTools.SetSelection[surfaceTool.conversionState.cadFile];
END;
BugCSFile: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
ViewerTools.SetSelection[surfaceTool.conversionState.csFile];
END;
BugDestDir: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
ViewerTools.SetSelection[surfaceTool.conversionState.destDir];
END;
BugDestFile: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
ViewerTools.SetSelection[surfaceTool.conversionState.destFile];
END;
BugConvert: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
sourceDir: Rope.ROPE ← ViewerTools.GetContents[surfaceTool.conversionState.sourceDir];
cadFile: Rope.ROPE ← ViewerTools.GetContents[surfaceTool.conversionState.cadFile];
csFile: Rope.ROPE ← ViewerTools.GetContents[surfaceTool.conversionState.csFile];
destDir: Rope.ROPE ← ViewerTools.GetContents[surfaceTool.conversionState.destDir];
destFile: Rope.ROPE ← ViewerTools.GetContents[surfaceTool.conversionState.destFile];
cadSource: Rope.ROPE ← Rope.Concat[sourceDir, cadFile];
csSource: Rope.ROPE ← Rope.Concat[sourceDir, csFile];
dest: Rope.ROPE ← Rope.Concat[destDir, destFile];
cad: CADTypes.Scad ← CADIO.ReadVAXCadFiles[cadSource, csSource];
CADIO.WriteInfoFile[dest, cad];
END;
Position/Orientation subviewer
PositionAndOrientationState: TYPE ~ RECORD [
Position State
position: Geometry3dVector.Triple ← [-6, 0, 0.2],
increment: REAL ← 0.1,
xDataLabel: Labels.Label ← NIL,
yDataLabel: Labels.Label ← NIL,
zDataLabel: Labels.Label ← NIL,
incrementLabel: Labels.Label ← NIL,
Orientation State
forward: Geometry3dVector.Triple ← [1, 0, 0],
up: Geometry3dVector.Triple ← [0, 0, 1],
angularIncrement: REAL ← 15.,
forwardXLabel: Labels.Label ← NIL,
forwardYLabel: Labels.Label ← NIL,
forwardZLabel: Labels.Label ← NIL,
upXLabel: Labels.Label ← NIL,
upYLabel: Labels.Label ← NIL,
upZLabel: Labels.Label ← NIL,
angularIncrementLabel: Labels.Label ← NIL];
BuildPositionSubviewer: PROC [surfaceTool: SurfaceToolRef] ~ BEGIN
Formatting constants.
baseX: CARDINAL ~ 5;
baseY: CARDINAL ~ surfaceTool.height + verticalSpacingAboveSubviewer;
topRow: CARDINAL ~ baseY;
subRow: CARDINAL ~ topRow + verticalHeight; -- + smallVerticalSpacing;
firstDataRow: CARDINAL ~ subRow + smallVerticalSpacing;
secondDataRow: CARDINAL ~ firstDataRow + verticalHeight + smallVerticalSpacing;
thirdDataRow: CARDINAL ~ secondDataRow + verticalHeight + smallVerticalSpacing;
fourthRow: CARDINAL ~ thirdDataRow + verticalHeight + smallVerticalSpacing;
bottomRow: CARDINAL ~ fourthRow + verticalHeight + smallVerticalSpacing;
plusColumn: CARDINAL ~ baseX;
plusButtonWidth: CARDINAL ~ VFonts.StringWidth[" +X "];
forwButtonWidth: CARDINAL ~ VFonts.StringWidth[" Forw "];
minusColumn: CARDINAL ~ plusColumn + forwButtonWidth + smallHorizontalSpacing;
minusButtonWidth: CARDINAL ~ VFonts.StringWidth[" -X "];
backButtonWidth: CARDINAL ~ VFonts.StringWidth[" Back "];
setColumn: CARDINAL ~ minusColumn + backButtonWidth + smallHorizontalSpacing;
setButtonWidth: CARDINAL ~ VFonts.StringWidth[" Set S "];
xyzLabelColumn: CARDINAL ~ setColumn + setButtonWidth + smallHorizontalSpacing;
xyzLabelWidth: CARDINAL ~ VFonts.StringWidth["Step:"];
dataViewerColumn: CARDINAL ~ xyzLabelColumn + xyzLabelWidth + smallHorizontalSpacing;
breakLineColumn: CARDINAL ~ dataViewerColumn + dataViewerWidth + largeHorizontalSpacing;
rotateOpsColumn: CARDINAL ~ breakLineColumn + largeHorizontalSpacing;
rotateOpsWidth: CARDINAL ~ VFonts.StringWidth["Angle: "];
rotateLeftColumn: CARDINAL ~ rotateOpsColumn + rotateOpsWidth + smallHorizontalSpacing;
rotateLeftWidth: CARDINAL ~ VFonts.StringWidth[" Left "];
rotateRightColumn: CARDINAL ~ rotateLeftColumn + dataViewerWidth + smallHorizontalSpacing;
rotateRightWidth: CARDINAL ~ VFonts.StringWidth[" Down "];
orientationLabelColumn: CARDINAL ~ rotateRightColumn + rotateRightWidth + smallHorizontalSpacing;
orientationLabelWidth: CARDINAL ~ VFonts.StringWidth["Fwd: "];
orientationXColumn: CARDINAL ~ orientationLabelColumn + orientationLabelWidth + smallHorizontalSpacing;
orientationYColumn: CARDINAL ~ orientationXColumn + dataViewerWidth + smallHorizontalSpacing;
orientationZColumn: CARDINAL ~ orientationYColumn + dataViewerWidth + smallHorizontalSpacing;
positionTitle: Rope.ROPE ~ "Position";
positionTitleColumn: CARDINAL ~ (breakLineColumn - VFonts.StringWidth[positionTitle])/2;
orientationTitle: Rope.ROPE ~ "Orientation";
orientationTitleColumn: CARDINAL ~ (toolWidth + breakLineColumn - VFonts.StringWidth[orientationTitle])/2;
Declare the rules that will be built.
hrule1, hrule2, hrule3, hrule4: Rules.Rule;
Build the title label.
[] ← BuildLabel [title, surfaceTool.outer, titleColumn, topRow, TRUE];
[] ← BuildLabel [positionTitle, surfaceTool.outer, positionTitleColumn, topRow, TRUE];
[] ← BuildLabel [orientationTitle, surfaceTool.outer, orientationTitleColumn, topRow, TRUE];
Build the position buttons and labels.
[] ← BuildButton [surfaceTool, "+X", plusColumn, firstDataRow, BugPlusX, TRUE, plusButtonWidth];
[] ← BuildButton [surfaceTool, "+Y", plusColumn, secondDataRow, BugPlusY, TRUE, plusButtonWidth];
[] ← BuildButton [surfaceTool, "+Z", plusColumn, thirdDataRow, BugPlusZ, TRUE, plusButtonWidth];
[] ← BuildButton [surfaceTool, "Forw", plusColumn, fourthRow, BugForward, TRUE, forwButtonWidth];
[] ← BuildButton [surfaceTool, "-X", minusColumn, firstDataRow, BugMinusX, TRUE, minusButtonWidth];
[] ← BuildButton [surfaceTool, "-Y", minusColumn, secondDataRow, BugMinusY, TRUE, minusButtonWidth];
[] ← BuildButton [surfaceTool, "-Z", minusColumn, thirdDataRow, BugMinusZ, TRUE, minusButtonWidth];
[] ← BuildButton [surfaceTool, "Back", minusColumn, fourthRow, BugBackward, TRUE, backButtonWidth];
[] ← BuildButton [surfaceTool, "Set X", setColumn, firstDataRow, BugNewX, TRUE, setButtonWidth];
[] ← BuildButton [surfaceTool, "Set Y", setColumn, secondDataRow, BugNewY, TRUE, setButtonWidth];
[] ← BuildButton [surfaceTool, "Set Z", setColumn, thirdDataRow, BugNewZ, TRUE, setButtonWidth];
[] ← BuildButton [surfaceTool, "Set S", setColumn, fourthRow, BugSetStep, TRUE, setButtonWidth];
[] ← BuildLabel ["x =", surfaceTool.outer, xyzLabelColumn, firstDataRow];
[] ← BuildLabel ["y =", surfaceTool.outer, xyzLabelColumn, secondDataRow];
[] ← BuildLabel ["z =", surfaceTool.outer, xyzLabelColumn, thirdDataRow];
[] ← BuildLabel ["Step:", surfaceTool.outer, xyzLabelColumn, fourthRow];
surfaceTool.positionAndOrientationState.xDataLabel ←
BuildDataLabel [surfaceTool.outer, dataViewerColumn, firstDataRow];
surfaceTool.positionAndOrientationState.yDataLabel ←
BuildDataLabel [surfaceTool.outer, dataViewerColumn, secondDataRow];
surfaceTool.positionAndOrientationState.zDataLabel ←
BuildDataLabel [surfaceTool.outer, dataViewerColumn, thirdDataRow];
surfaceTool.positionAndOrientationState.incrementLabel ←
BuildDataLabel [surfaceTool.outer, dataViewerColumn, fourthRow];
Build the Turn, Roll, and Dive labels and buttons.
[] ← Labels.Create[[name: "Turn", wx: rotateOpsColumn, wy: firstDataRow, wh: verticalHeight, parent: surfaceTool.outer, border: FALSE]];
[] ← BuildButton[surfaceTool, "Left", rotateLeftColumn, firstDataRow, BugTurnLeft, TRUE, rotateLeftWidth];
[] ← BuildButton[surfaceTool, "Right", rotateRightColumn, firstDataRow, BugTurnRight, TRUE, rotateRightWidth];
[] ← Labels.Create[[name: "Roll", wx: rotateOpsColumn, wy: secondDataRow, wh: verticalHeight, parent: surfaceTool.outer, border: FALSE]];
[] ← BuildButton[surfaceTool, "Left", rotateLeftColumn, secondDataRow, BugRollLeft, TRUE, rotateLeftWidth];
[] ← BuildButton[surfaceTool, "Right", rotateRightColumn, secondDataRow, BugRollRight, TRUE, rotateRightWidth];
[] ← Labels.Create[[name: "Dive", wx: rotateOpsColumn, wy: thirdDataRow, wh: verticalHeight, parent: surfaceTool.outer, border: FALSE]];
[] ← BuildButton[surfaceTool, "Up", rotateLeftColumn, thirdDataRow, BugClimb, TRUE];
[] ← BuildButton[surfaceTool, "Down", rotateRightColumn, thirdDataRow, BugDive, TRUE, rotateRightWidth];
Build the angular increment button and label.
[] ← BuildLabel ["Angle:", surfaceTool.outer, rotateOpsColumn, fourthRow];
surfaceTool.positionAndOrientationState.angularIncrementLabel ←
BuildDataLabel [surfaceTool.outer, rotateLeftColumn, fourthRow];
[] ← BuildButton [surfaceTool, "Set A", rotateRightColumn, fourthRow, BugSetAngularStep, TRUE, rotateRightWidth];
Build the orientation vector labels and buttons.
[] ← Labels.Create[[name: "Fwd:", wx: orientationLabelColumn, wy: firstDataRow, wh: verticalHeight, parent: surfaceTool.outer, border: FALSE]];
[] ← Labels.Create[[name: "Up:", wx: orientationLabelColumn, wy: secondDataRow, wh: verticalHeight, parent: surfaceTool.outer, border: FALSE]];
surfaceTool.positionAndOrientationState.forwardXLabel ←
BuildDataLabel[surfaceTool.outer, orientationXColumn, firstDataRow];
surfaceTool.positionAndOrientationState.forwardYLabel ←
BuildDataLabel[surfaceTool.outer, orientationYColumn, firstDataRow];
surfaceTool.positionAndOrientationState.forwardZLabel ←
BuildDataLabel[surfaceTool.outer, orientationZColumn, firstDataRow];
surfaceTool.positionAndOrientationState.upXLabel ←
BuildDataLabel[surfaceTool.outer, orientationXColumn, secondDataRow];
surfaceTool.positionAndOrientationState.upYLabel ←
BuildDataLabel[surfaceTool.outer, orientationYColumn, secondDataRow];
surfaceTool.positionAndOrientationState.upZLabel ←
BuildDataLabel[surfaceTool.outer, orientationZColumn, secondDataRow];
Build the Fancy Maneuvers button.
[] ← BuildButton[surfaceTool, "Fancy maneuvers", orientationXColumn, fourthRow, BugFancy, TRUE];
Fill in the numbers.
UpdatePositionAndOrientationData[surfaceTool];
Draw the vertical rule.
[] ← Rules.Create [[wx: breakLineColumn, wy: subRow, ww: 1, wh: bottomRow - subRow, parent: surfaceTool.outer]];
Draw the horizontal lines and constrain them to be the width of the tool.
hrule1 ← Rules.Create [[wx: 0, wy: topRow, wh: 1, parent: surfaceTool.outer]];
hrule2 ← Rules.Create [[wx: 0, wy: subRow, wh: 1, parent: surfaceTool.outer]];
hrule3 ← Rules.Create [[wx: 0, wy: bottomRow, wh: 1, parent: surfaceTool.outer]];
Containers.ChildXBound[surfaceTool.outer, hrule1];
Containers.ChildXBound[surfaceTool.outer, hrule2];
Containers.ChildXBound[surfaceTool.outer, hrule3];
Draw the lower-right-hand-corner rules.
[] ← Rules.Create [[wx: orientationLabelColumn, wy: thirdDataRow, ww: 1, wh: bottomRow - thirdDataRow, parent: surfaceTool.outer]];
hrule4 ← Rules.Create [[wx: orientationLabelColumn, wy: thirdDataRow, wh: 1, parent: surfaceTool.outer]];
Containers.ChildXBound[surfaceTool.outer, hrule4];
Extend the tool's height.
surfaceTool.height ← surfaceTool.height + bottomRow - baseY + 1 + verticalSpacingBelowSubviewer;
END;
UpdatePositionAndOrientationData: PROC[surfaceTool: SurfaceToolRef] ~ BEGIN
Update the position labels.
Labels.Set[surfaceTool.positionAndOrientationState.xDataLabel, RopeFromReal[surfaceTool.positionAndOrientationState.position.x]];
Labels.Set[surfaceTool.positionAndOrientationState.yDataLabel, RopeFromReal[surfaceTool.positionAndOrientationState.position.y]];
Labels.Set[surfaceTool.positionAndOrientationState.zDataLabel, RopeFromReal[surfaceTool.positionAndOrientationState.position.z]];
Labels.Set[surfaceTool.positionAndOrientationState.incrementLabel, RopeFromReal[surfaceTool.positionAndOrientationState.increment]];
Update the orientation labels.
Labels.Set[surfaceTool.positionAndOrientationState.forwardXLabel, RopeFromReal[surfaceTool.positionAndOrientationState.forward.x]];
Labels.Set[surfaceTool.positionAndOrientationState.forwardYLabel, RopeFromReal[surfaceTool.positionAndOrientationState.forward.y]];
Labels.Set[surfaceTool.positionAndOrientationState.forwardZLabel, RopeFromReal[surfaceTool.positionAndOrientationState.forward.z]];
Labels.Set[surfaceTool.positionAndOrientationState.upXLabel, RopeFromReal[surfaceTool.positionAndOrientationState.up.x]];
Labels.Set[surfaceTool.positionAndOrientationState.upYLabel, RopeFromReal[surfaceTool.positionAndOrientationState.up.y]];
Labels.Set[surfaceTool.positionAndOrientationState.upZLabel, RopeFromReal[surfaceTool.positionAndOrientationState.up.z]];
Labels.Set[surfaceTool.positionAndOrientationState.angularIncrementLabel, Convert.RopeFromInt[Real.InlineFix[surfaceTool.positionAndOrientationState.angularIncrement]]];
END;
BugPlusX: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
surfaceTool.positionAndOrientationState.position.x ← surfaceTool.positionAndOrientationState.position.x + surfaceTool.positionAndOrientationState.increment;
UpdatePositionAndOrientationData[surfaceTool];
END;
BugPlusY: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
surfaceTool.positionAndOrientationState.position.y ← surfaceTool.positionAndOrientationState.position.y + surfaceTool.positionAndOrientationState.increment;
UpdatePositionAndOrientationData[surfaceTool];
END;
BugPlusZ: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
surfaceTool.positionAndOrientationState.position.z ← surfaceTool.positionAndOrientationState.position.z + surfaceTool.positionAndOrientationState.increment;
UpdatePositionAndOrientationData[surfaceTool];
END;
BugMinusX: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
surfaceTool.positionAndOrientationState.position.x ← surfaceTool.positionAndOrientationState.position.x - surfaceTool.positionAndOrientationState.increment;
UpdatePositionAndOrientationData[surfaceTool];
END;
BugMinusY: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
surfaceTool.positionAndOrientationState.position.y ← surfaceTool.positionAndOrientationState.position.y - surfaceTool.positionAndOrientationState.increment;
UpdatePositionAndOrientationData[surfaceTool];
END;
BugMinusZ: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
surfaceTool.positionAndOrientationState.position.z ← surfaceTool.positionAndOrientationState.position.z - surfaceTool.positionAndOrientationState.increment;
UpdatePositionAndOrientationData[surfaceTool];
END;
BugNewX: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
value: REAL ← GetRealSelection[surfaceTool.positionAndOrientationState.position.x];
surfaceTool.positionAndOrientationState.position.x ← value;
UpdatePositionAndOrientationData[surfaceTool];
END;
BugNewY: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
value: REAL ← GetRealSelection[surfaceTool.positionAndOrientationState.position.y];
surfaceTool.positionAndOrientationState.position.y ← value;
UpdatePositionAndOrientationData[surfaceTool];
END;
BugNewZ: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
value: REAL ← GetRealSelection[surfaceTool.positionAndOrientationState.position.z];
surfaceTool.positionAndOrientationState.position.z ← value;
UpdatePositionAndOrientationData[surfaceTool];
END;
BugSetStep: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
value: REAL ← GetRealSelection[surfaceTool.positionAndOrientationState.increment];
surfaceTool.positionAndOrientationState.increment ← value;
UpdatePositionAndOrientationData[surfaceTool];
END;
BugTurnLeft: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
axis: Geometry3dVector.Triple ← surfaceTool.positionAndOrientationState.up;
rotationMatrix: Geometry3dMatrix.Matrix ← Geometry3dMatrix.MakePureRotate[axis, -(surfaceTool.positionAndOrientationState.angularIncrement)];
oldForward: Geometry3dVector.Triple ← surfaceTool.positionAndOrientationState.forward;
newForward: Geometry3dVector.Triple ← Geometry3dMatrix.Transform[oldForward, rotationMatrix];
surfaceTool.positionAndOrientationState.forward ← newForward;
UpdatePositionAndOrientationData[surfaceTool];
END;
BugTurnRight: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
axis: Geometry3dVector.Triple ← surfaceTool.positionAndOrientationState.up;
rotationMatrix: Geometry3dMatrix.Matrix ← Geometry3dMatrix.MakePureRotate[axis, surfaceTool.positionAndOrientationState.angularIncrement];
oldForward: Geometry3dVector.Triple ← surfaceTool.positionAndOrientationState.forward;
newForward: Geometry3dVector.Triple ← Geometry3dMatrix.Transform[oldForward, rotationMatrix];
surfaceTool.positionAndOrientationState.forward ← newForward;
UpdatePositionAndOrientationData[surfaceTool];
END;
BugRollLeft: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
axis: Geometry3dVector.Triple ← surfaceTool.positionAndOrientationState.forward;
rotationMatrix: Geometry3dMatrix.Matrix ← Geometry3dMatrix.MakePureRotate[axis, surfaceTool.positionAndOrientationState.angularIncrement];
oldUp: Geometry3dVector.Triple ← surfaceTool.positionAndOrientationState.up;
newUp: Geometry3dVector.Triple ← Geometry3dMatrix.Transform[oldUp, rotationMatrix];
surfaceTool.positionAndOrientationState.up ← newUp;
UpdatePositionAndOrientationData[surfaceTool];
END;
BugRollRight: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
axis: Geometry3dVector.Triple ← surfaceTool.positionAndOrientationState.forward;
rotationMatrix: Geometry3dMatrix.Matrix ← Geometry3dMatrix.MakePureRotate[axis, -(surfaceTool.positionAndOrientationState.angularIncrement)];
oldUp: Geometry3dVector.Triple ← surfaceTool.positionAndOrientationState.up;
newUp: Geometry3dVector.Triple ← Geometry3dMatrix.Transform[oldUp, rotationMatrix];
surfaceTool.positionAndOrientationState.up ← newUp;
UpdatePositionAndOrientationData[surfaceTool];
END;
BugClimb: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
Rotation axis is side-to-side, perpendicular to both the forward and the up vectors.
axis: Geometry3dVector.Triple ← Geometry3dVector.Cross[surfaceTool.positionAndOrientationState.forward, surfaceTool.positionAndOrientationState.up];
rotationMatrix: Geometry3dMatrix.Matrix ← Geometry3dMatrix.MakePureRotate[axis, -(surfaceTool.positionAndOrientationState.angularIncrement)];
oldUp: Geometry3dVector.Triple ← surfaceTool.positionAndOrientationState.up;
oldForward: Geometry3dVector.Triple ← surfaceTool.positionAndOrientationState.forward;
newUp: Geometry3dVector.Triple ← Geometry3dMatrix.Transform[oldUp, rotationMatrix];
newForward: Geometry3dVector.Triple ← Geometry3dMatrix.Transform[oldForward, rotationMatrix];
surfaceTool.positionAndOrientationState.up ← newUp;
surfaceTool.positionAndOrientationState.forward ← newForward;
UpdatePositionAndOrientationData[surfaceTool];
END;
BugDive: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
Rotation axis is side-to-side, perpendicular to both the forward and the up vectors.
axis: Geometry3dVector.Triple ← Geometry3dVector.Cross[surfaceTool.positionAndOrientationState.forward, surfaceTool.positionAndOrientationState.up];
rotationMatrix: Geometry3dMatrix.Matrix ← Geometry3dMatrix.MakePureRotate[axis, surfaceTool.positionAndOrientationState.angularIncrement];
oldUp: Geometry3dVector.Triple ← surfaceTool.positionAndOrientationState.up;
oldForward: Geometry3dVector.Triple ← surfaceTool.positionAndOrientationState.forward;
newUp: Geometry3dVector.Triple ← Geometry3dMatrix.Transform[oldUp, rotationMatrix];
newForward: Geometry3dVector.Triple ← Geometry3dMatrix.Transform[oldForward, rotationMatrix];
surfaceTool.positionAndOrientationState.up ← newUp;
surfaceTool.positionAndOrientationState.forward ← newForward;
UpdatePositionAndOrientationData[surfaceTool];
END;
BugSetAngularStep: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
value: REAL ← GetRealSelection[surfaceTool.positionAndOrientationState.angularIncrement];
surfaceTool.positionAndOrientationState.angularIncrement ← value;
UpdatePositionAndOrientationData[surfaceTool];
END;
BugForward: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
displacement: Geometry3dVector.Triple ← Geometry3dVector.Mul[surfaceTool.positionAndOrientationState.forward, surfaceTool.positionAndOrientationState.increment];
surfaceTool.positionAndOrientationState.position ← Geometry3dVector.Add[surfaceTool.positionAndOrientationState.position, displacement];
UpdatePositionAndOrientationData[surfaceTool];
END;
BugBackward: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
displacement: Geometry3dVector.Triple ← Geometry3dVector.Mul[surfaceTool.positionAndOrientationState.forward, surfaceTool.positionAndOrientationState.increment];
surfaceTool.positionAndOrientationState.position ← Geometry3dVector.Sub[surfaceTool.positionAndOrientationState.position, displacement];
UpdatePositionAndOrientationData[surfaceTool];
END;
BugFancy: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
options: LIST OF Rope.ROPELIST[
"Turn around",
"Go to origin",
"Look towards origin",
"Look towards origin from +x axis",
"Look towards origin from +y axis",
"Look towards origin from +z axis",
"Look towards origin from -x axis",
"Look towards origin from -y axis",
"Look towards origin from -z axis",
"Look in +x direction",
"Look in +y direction",
"Look in +z direction",
"Look toward origin from +++ octant",
"Look toward origin from ++— octant",
"Look toward origin from +—+ octant",
"Look toward origin from +—— octant",
"Look toward origin from —++ octant",
"Look toward origin from —+— octant",
"Look toward origin from ——+ octant",
"Look toward origin from ——— octant",
];
selection: INT ← PopUpSelection.Request[
header: "Fancy maneuvers",
choice: options];
SELECT selection FROM
-1 => NULL; -- Timeout
0 => NULL; -- No selection
1 =>  -- Turn around
surfaceTool.positionAndOrientationState.forward ← Geometry3dVector.Mul[surfaceTool.positionAndOrientationState.forward, -1];
2 => { -- Go to originB
surfaceTool.positionAndOrientationState.position ← [0, 0, 0];
};
3 => { -- Look towards origin
forward: Geometry3dVector.Triple ← Geometry3dVector.Negate[surfaceTool.positionAndOrientationState.position];
surfaceTool.positionAndOrientationState.forward ← Geometry3dVector.Normalize[forward];
surfaceTool.positionAndOrientationState.up ← Geometry3dVector.Ortho[forward, [1,0,0] ];
};
4 => { -- Look toward origin from +x axis
surfaceTool.positionAndOrientationState.position ← [10, 0, 0];
surfaceTool.positionAndOrientationState.forward ← [-1, 0, 0];
surfaceTool.positionAndOrientationState.up ← [0, 0, 1];
};
5 => { -- Look toward origin from +y axis
surfaceTool.positionAndOrientationState.position ← [0, 10, 0];
surfaceTool.positionAndOrientationState.forward ← [0, -1, 0];
surfaceTool.positionAndOrientationState.up ← [0, 0, 1];
};
6 => { -- Look toward origin from +z axis
surfaceTool.positionAndOrientationState.position ← [0, 0, 10];
surfaceTool.positionAndOrientationState.forward ← [0, 0, -1];
surfaceTool.positionAndOrientationState.up ← [0, 1, 0];
};
7 => { -- Look toward origin from -x axis
surfaceTool.positionAndOrientationState.position ← [-10, 0, 0];
surfaceTool.positionAndOrientationState.forward ← [1, 0, 0];
surfaceTool.positionAndOrientationState.up ← [0, 0, 1];
};
8 => { -- Look toward origin from -y axis
surfaceTool.positionAndOrientationState.position ← [0, -10, 0];
surfaceTool.positionAndOrientationState.forward ← [0, 1, 0];
surfaceTool.positionAndOrientationState.up ← [0, 0, 1];
};
9 => { -- Look toward origin from -z axis
surfaceTool.positionAndOrientationState.position ← [0, 0, -10];
surfaceTool.positionAndOrientationState.forward ← [0, 0, 1];
surfaceTool.positionAndOrientationState.up ← [0, 1, 0];
};
10 => { -- Look in +x direction
surfaceTool.positionAndOrientationState.forward ← [1, 0, 0];
surfaceTool.positionAndOrientationState.up ← [0, 0, 1];
};
11 => { -- Look in +y direction
surfaceTool.positionAndOrientationState.forward ← [0, 1, 0];
surfaceTool.positionAndOrientationState.up ← [0, 0, 1];
};
12 => { -- Look in +z direction
surfaceTool.positionAndOrientationState.forward ← [0, 0, 1];
surfaceTool.positionAndOrientationState.up ← [0, 1, 0];
};
13 => {
surfaceTool.positionAndOrientationState.position ← [3, 3, 3];
surfaceTool.positionAndOrientationState.forward ← Geometry3dVector.Normalize[[-1, -1, -1]];
surfaceTool.positionAndOrientationState.up ← [0, 0, 1];
};
14 => {
surfaceTool.positionAndOrientationState.position ← [3, 3, -3];
surfaceTool.positionAndOrientationState.forward ← Geometry3dVector.Normalize[[-1, -1, 1]];
surfaceTool.positionAndOrientationState.up ← [0, 0, 1];
};
15 => {
surfaceTool.positionAndOrientationState.position ← [3, -3, 3];
surfaceTool.positionAndOrientationState.forward ← Geometry3dVector.Normalize[[-1, 1, -1]];
surfaceTool.positionAndOrientationState.up ← [0, 0, 1];
};
16 => {
surfaceTool.positionAndOrientationState.position ← [3, -3, -3];
surfaceTool.positionAndOrientationState.forward ← Geometry3dVector.Normalize[[-1, 1, 1]];
surfaceTool.positionAndOrientationState.up ← [0, 0, 1];
};
17 => {
surfaceTool.positionAndOrientationState.position ← [-3, 3, 3];
surfaceTool.positionAndOrientationState.forward ← Geometry3dVector.Normalize[[1, -1, -1]];
surfaceTool.positionAndOrientationState.up ← [0, 0, 1];
};
18 => {
surfaceTool.positionAndOrientationState.position ← [-3, 3, -3];
surfaceTool.positionAndOrientationState.forward ← Geometry3dVector.Normalize[[1, -1, 1]];
surfaceTool.positionAndOrientationState.up ← [0, 0, 1];
};
19 => {
surfaceTool.positionAndOrientationState.position ← [-3, -3, 3];
surfaceTool.positionAndOrientationState.forward ← Geometry3dVector.Normalize[[1, 1, -1]];
surfaceTool.positionAndOrientationState.up ← [0, 0, 1];
};
20 => {
surfaceTool.positionAndOrientationState.position ← [-3, -3, -3];
surfaceTool.positionAndOrientationState.forward ← Geometry3dVector.Normalize[[1, 1, 1]];
surfaceTool.positionAndOrientationState.up ← [0, 0, 1];
};
ENDCASE => NULL;
UpdatePositionAndOrientationData[surfaceTool];
END;
Active surfaces subviewer
ActiveState: TYPE ~ RECORD [
surfaces: REF ActiveSurfaceSequence,
selectedSurface: NAT ← 0, -- 0=none
dir: ViewerClasses.Viewer ← NIL,
filename: ViewerClasses.Viewer ← NIL
];
ActiveSurfaceRec: TYPE ~ RECORD [
button: Buttons.Button ← NIL,
viewer: ViewerClasses.Viewer ← NIL,
visibleLabel: Labels.Label ← NIL,
surfaceID: NAT,
isLoaded: BOOLEANFALSE,
cad: CADTypes.Scad,
mask: REF CADTypes.VisibleMask,
isVisible: BOOLEANTRUE
];
ActiveSurfaceSequence: TYPE ~ RECORD [
activeSurfaceRecs: SEQUENCE length: NAT OF ActiveSurfaceRec];
BuildActiveSubviewer: PROC [surfaceTool: SurfaceToolRef] ~ BEGIN
Formatting constants.
baseX: CARDINAL ~ 5;
baseY: CARDINAL ~ surfaceTool.height + verticalSpacingAboveSubviewer;
topRow: CARDINAL ~ baseY;
subRow: CARDINAL ~ topRow + verticalHeight;
activeBlockX: CARDINAL ~ 20;
activeBlockY: CARDINAL ~ baseY;
activeTitle: Rope.ROPE ~ "Active Surfaces";
activeTitleRow: CARDINAL ~ activeBlockY;
activeTitleColumn: CARDINAL ~ (toolWidth - VFonts.StringWidth[activeTitle])/2;
activeLetterColumn: CARDINAL ~ activeBlockX;
activeLetterButtonWidth: CARDINAL ~ VFonts.StringWidth[" B "];
activeNameColumn: CARDINAL ~ activeLetterColumn + activeLetterButtonWidth + smallHorizontalSpacing;
activeNameViewerWidth: CARDINAL ~ (toolWidth/2) - activeNameColumn;
activeVisibleColumn: CARDINAL ~ activeNameColumn + activeNameViewerWidth + smallHorizontalSpacing;
activeVisibleLabelWidth: CARDINAL ~ 20;
activeFirstButtonColumn: CARDINAL ~ activeVisibleColumn + activeVisibleLabelWidth + smallHorizontalSpacing;
activeFirstButtonWidth: CARDINAL ~ VFonts.StringWidth[" Set color "];
activeSecondButtonColumn: CARDINAL ~ activeFirstButtonColumn + activeFirstButtonWidth + smallHorizontalSpacing;
activeSecondButtonWidth: CARDINAL ~ VFonts.StringWidth[" Show/Don't show "];
activeIOLabelColumn: CARDINAL ~ activeBlockX;
cellLabelColumn: CARDINAL ~ activeBlockX;
cellButtonSpacing: CARDINAL ~ VFonts.StringWidth[" Reveal One "];
cellFirstButtonColumn: CARDINAL ~ cellLabelColumn + cellButtonSpacing;
cellSecondButtonColumn: CARDINAL ~ cellFirstButtonColumn + cellButtonSpacing;
cellThirdButtonColumn: CARDINAL ~ cellSecondButtonColumn + cellButtonSpacing;
cellFourthButtonColumn: CARDINAL ~ cellThirdButtonColumn + cellButtonSpacing;
cellFifthButtonColumn: CARDINAL ~ cellFourthButtonColumn + cellButtonSpacing;
activeIOLabelWidth: CARDINAL ~ VFonts.StringWidth[" Working dir: "];
activeIOViewerColumn: CARDINAL ~ activeIOLabelColumn + activeIOLabelWidth + smallHorizontalSpacing;
activeIOViewerWidth: CARDINAL ~ (toolWidth/2);
activeIOButtonColumn: CARDINAL ~ activeIOViewerColumn + activeIOViewerWidth + smallHorizontalSpacing;
activeIOButtonWidth: CARDINAL ~ VFonts.StringWidth[" Store "];
activeARow: CARDINAL ~ activeTitleRow + verticalHeight + smallVerticalSpacing;
activeBRow: CARDINAL ~ activeARow + verticalHeight + smallVerticalSpacing;
activeCRow: CARDINAL ~ activeBRow + verticalHeight + smallVerticalSpacing;
activeDirRow: CARDINAL ~ activeCRow + verticalHeight + 2 * smallVerticalSpacing;
activeFileRow: CARDINAL ~ activeDirRow + verticalHeight + smallVerticalSpacing;
cellRow: CARDINAL ~ activeFileRow + verticalHeight + 2 * smallVerticalSpacing;
bottomRow: CARDINAL ~ cellRow + verticalHeight + smallVerticalSpacing;
Declare the rules that will be built.
hrule1, hrule2, hrule3: Rules.Rule;
Instantiate the activeState.
surfaceTool.activeState.surfaces ← NEW[ActiveSurfaceSequence[3]];
Build the title.
[] ← BuildLabel [activeTitle, surfaceTool.outer, activeTitleColumn, activeTitleRow, TRUE];
Build the letter buttons.
surfaceTool.activeState.surfaces[0].button ← BuildButton [surfaceTool, "A", activeLetterColumn, activeARow, BugA, TRUE, activeLetterButtonWidth];
surfaceTool.activeState.surfaces[1].button ← BuildButton [surfaceTool, "B", activeLetterColumn, activeBRow, BugB, TRUE, activeLetterButtonWidth];
surfaceTool.activeState.surfaces[2].button ← BuildButton [surfaceTool, "C", activeLetterColumn, activeCRow, BugC, TRUE, activeLetterButtonWidth];
Build the name/equation viewers.
surfaceTool.activeState.surfaces[0].viewer ← BuildTextViewer [surfaceTool.outer, activeNameColumn, activeARow, activeNameViewerWidth];
surfaceTool.activeState.surfaces[1].viewer ← BuildTextViewer [surfaceTool.outer, activeNameColumn, activeBRow, activeNameViewerWidth];
surfaceTool.activeState.surfaces[2].viewer ← BuildTextViewer [surfaceTool.outer, activeNameColumn, activeCRow, activeNameViewerWidth];
Build the visible labels.
surfaceTool.activeState.surfaces[0].visibleLabel ← BuildLabel ["N", surfaceTool.outer, activeVisibleColumn, activeARow, FALSE];
surfaceTool.activeState.surfaces[1].visibleLabel ← BuildLabel ["N", surfaceTool.outer, activeVisibleColumn, activeBRow, FALSE];
surfaceTool.activeState.surfaces[2].visibleLabel ← BuildLabel ["N", surfaceTool.outer, activeVisibleColumn, activeCRow, FALSE];
Build some buttons.
[] ← BuildButton [surfaceTool, "Rename", activeFirstButtonColumn, activeARow, BugRename, TRUE, activeFirstButtonWidth];
[] ← BuildButton [surfaceTool, "Delete", activeFirstButtonColumn, activeBRow, BugDelete, TRUE, activeFirstButtonWidth];
[] ← BuildButton [surfaceTool, "Set color", activeFirstButtonColumn, activeCRow, BugSetColor, TRUE, activeFirstButtonWidth];
[] ← BuildButton [surfaceTool, "Name/Formula", activeSecondButtonColumn, activeARow, BugName, TRUE, activeSecondButtonWidth];
[] ← BuildButton [surfaceTool, "Show/Don't Show", activeSecondButtonColumn, activeBRow, BugShow, TRUE, activeSecondButtonWidth];
[] ← BuildButton [surfaceTool, "Set Render Mode", activeSecondButtonColumn, activeCRow, BugSetRenderMode, TRUE, activeSecondButtonWidth];
Build the directory and file buttons.
[] ← BuildButton [surfaceTool, "Working dir:", activeIOLabelColumn, activeDirRow, BugDir, TRUE, activeIOLabelWidth];
[] ← BuildButton [surfaceTool, "File name:", activeIOLabelColumn, activeFileRow, BugFile, TRUE, activeIOLabelWidth];
Build the directory and file viewers.
surfaceTool.activeState.dir ← BuildTextViewer [surfaceTool.outer, activeIOViewerColumn, activeDirRow, activeIOViewerWidth];
surfaceTool.activeState.filename ← BuildTextViewer [surfaceTool.outer, activeIOViewerColumn, activeFileRow, activeIOViewerWidth];
ViewerTools.SetContents[surfaceTool.activeState.dir, UserProfile.Token["AlgebraicSurfaces.Directory"]];
Build the load and store buttons.
[] ← BuildButton [surfaceTool, "Load", activeIOButtonColumn, activeDirRow, BugLoadSurface, TRUE, activeIOButtonWidth];
[] ← BuildButton [surfaceTool, "Store", activeIOButtonColumn, activeFileRow, BugStore, TRUE, activeIOButtonWidth];
Build the cell operation labels and buttons.
[] ← BuildLabel ["Cell Ops:", surfaceTool.outer, cellLabelColumn, cellRow, TRUE];
[] ← BuildButton [surfaceTool, "Hide All", cellFirstButtonColumn, cellRow, BugHideAll, TRUE];
[] ← BuildButton [surfaceTool, "Hide One", cellSecondButtonColumn, cellRow, BugHideOne, TRUE];
[] ← BuildButton [surfaceTool, "Reveal All", cellThirdButtonColumn, cellRow, BugRevealAll, TRUE];
[] ← BuildButton [surfaceTool, "Reveal One", cellFourthButtonColumn, cellRow, BugRevealOne, TRUE];
[] ← BuildButton [surfaceTool, "List All", cellFifthButtonColumn, cellRow, BugListAll, TRUE];
Draw the horizontal lines and constrain them to be the width of the tool.
hrule1 ← Rules.Create [[wx: 0, wy: topRow, wh: 1, parent: surfaceTool.outer]];
hrule2 ← Rules.Create [[wx: 0, wy: subRow, wh: 1, parent: surfaceTool.outer]];
hrule3 ← Rules.Create [[wx: 0, wy: bottomRow, wh: 1, parent: surfaceTool.outer]];
Containers.ChildXBound[surfaceTool.outer, hrule1];
Containers.ChildXBound[surfaceTool.outer, hrule2];
Containers.ChildXBound[surfaceTool.outer, hrule3];
Extend the tool's height.
surfaceTool.height ← surfaceTool.height + bottomRow - baseY + 1 + verticalSpacingBelowSubviewer;
END;
BugA: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
IF surfaceTool.activeState.surfaces[0].isLoaded THEN BEGIN
surfaceTool.activeState.selectedSurface ← 0;
ViewerTools.SetSelection[surfaceTool.activeState.surfaces[0].viewer];
RepaintLetterButtons[surfaceTool];
END;
END;
BugB: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
IF surfaceTool.activeState.surfaces[1].isLoaded THEN BEGIN
surfaceTool.activeState.selectedSurface ← 1;
ViewerTools.SetSelection[surfaceTool.activeState.surfaces[1].viewer];
RepaintLetterButtons[surfaceTool];
END;
END;
BugC: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
IF surfaceTool.activeState.surfaces[2].isLoaded THEN BEGIN
surfaceTool.activeState.selectedSurface ← 2;
ViewerTools.SetSelection[surfaceTool.activeState.surfaces[2].viewer];
RepaintLetterButtons[surfaceTool];
END;
END;
RepaintLetterButtons: PROC [surfaceTool: SurfaceToolRef] ~ BEGIN
RepaintLetterButtonsError: ERROR = CODE;
Buttons.SetDisplayStyle [surfaceTool.activeState.surfaces[0].button, $BlackOnWhite];
Buttons.SetDisplayStyle [surfaceTool.activeState.surfaces[1].button, $BlackOnWhite];
Buttons.SetDisplayStyle [surfaceTool.activeState.surfaces[2].button, $BlackOnWhite];
SELECT surfaceTool.activeState.selectedSurface FROM
0 => Buttons.SetDisplayStyle [surfaceTool.activeState.surfaces[0].button, $WhiteOnBlack];
1 => Buttons.SetDisplayStyle [surfaceTool.activeState.surfaces[1].button, $WhiteOnBlack];
2 => Buttons.SetDisplayStyle [surfaceTool.activeState.surfaces[2].button, $WhiteOnBlack];
ENDCASE => ERROR RepaintLetterButtonsError;
END;
RedrawEquationViewers: PROC [surfaceTool: SurfaceToolRef] ~ BEGIN
FOR i: NAT IN [0..3) DO
IF surfaceTool.activeState.surfaces[i].isLoaded THEN BEGIN
ViewerTools.SetContents[surfaceTool.activeState.surfaces[i].viewer, MultiPolynomial.RopeFromRef[surfaceTool.activeState.surfaces[i].cad.surface]];
Labels.Set[
surfaceTool.activeState.surfaces[i].visibleLabel,
IF surfaceTool.activeState.surfaces[i].isVisible THEN "Y" ELSE "N"];
END
ELSE BEGIN
ViewerTools.SetContents[surfaceTool.activeState.surfaces[i].viewer, ""];
Labels.Set[surfaceTool.activeState.surfaces[i].visibleLabel, "-"];
END;
ENDLOOP;
END;
BugRename: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
END;
BugDelete: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
selectedSurface: NAT ← surfaceTool.activeState.selectedSurface;
IF surfaceTool.activeState.surfaces[selectedSurface].isLoaded THEN BEGIN
SurfaceViewer.DeleteSurface[surfaceTool.activeState.surfaces[selectedSurface].surfaceID, surfaceTool.sviewer];
surfaceTool.activeState.surfaces[selectedSurface].isLoaded ← FALSE;
RedrawEquationViewers[surfaceTool];
END;
END;
BugSetColor: Buttons.ButtonProc ~ BEGIN
selection: INT;
id: NAT;
surfaceTool: SurfaceToolRef ← NARROW[clientData];
options: LIST OF Rope.ROPELIST["Light Gray (0.3)", "Dark Gray (0.6)", "Red", "Green", "Blue"];
selectedSurface: NAT ← surfaceTool.activeState.selectedSurface;
IF surfaceTool.activeState.surfaces[selectedSurface].isLoaded = FALSE THEN BEGIN
FlashMessage["No selected surface"];
RETURN;
END;
id ← surfaceTool.activeState.surfaces[selectedSurface].surfaceID;
selection ← PopUpSelection.Request[
header: "Select a color:",
choice: options];
SELECT selection FROM
-1 => NULL; -- Timeout
0 => NULL; -- No selection
1 => SurfaceViewer.SetSurfaceColor[id, [0.3, 0.3, 0.3], surfaceTool.sviewer];
2 => SurfaceViewer.SetSurfaceColor[id, [0.6, 0.6, 0.6], surfaceTool.sviewer];
3 => SurfaceViewer.SetSurfaceColor[id, [0.8, 0.2, 0.2], surfaceTool.sviewer];
4 => SurfaceViewer.SetSurfaceColor[id, [0.2, 0.8, 0.2], surfaceTool.sviewer];
5 => SurfaceViewer.SetSurfaceColor[id, [0.2, 0.2, 0.8], surfaceTool.sviewer];
ENDCASE => NULL;
END;
BugName: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
END;
BugShow: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
selectedSurface: NAT ← surfaceTool.activeState.selectedSurface;
IF surfaceTool.activeState.surfaces[selectedSurface].isLoaded THEN BEGIN
IF surfaceTool.activeState.surfaces[selectedSurface].isVisible THEN BEGIN
SurfaceViewer.HideSurface [surfaceTool.activeState.surfaces[selectedSurface].surfaceID, surfaceTool.sviewer];
surfaceTool.activeState.surfaces[selectedSurface].isVisible ← FALSE;
END
ELSE BEGIN
SurfaceViewer.UnHideSurface [surfaceTool.activeState.surfaces[selectedSurface].surfaceID, surfaceTool.sviewer];
surfaceTool.activeState.surfaces[selectedSurface].isVisible ← TRUE;
END;
RedrawEquationViewers[surfaceTool];
END;
END;
BugSetRenderMode: Buttons.ButtonProc ~ BEGIN
selection: INT;
id: NAT;
surfaceTool: SurfaceToolRef ← NARROW[clientData];
options: LIST OF Rope.ROPELIST["Lines", "Faceted", "Smooth", "Hidden Lines", "Normaled Lines", "Shaded Lines"];
selectedSurface: NAT ← surfaceTool.activeState.selectedSurface;
IF surfaceTool.activeState.surfaces[selectedSurface].isLoaded = FALSE THEN BEGIN
FlashMessage["No selected surface"];
RETURN;
END;
id ← surfaceTool.activeState.surfaces[selectedSurface].surfaceID;
selection ← PopUpSelection.Request[
header: "Select a rendering mode",
choice: options];
SELECT selection FROM
-1 => NULL; -- Timeout
0 => NULL; -- No selection
1 => SurfaceViewer.SetSurfaceRenderingMode[id, $Lines, surfaceTool.sviewer];
2 => SurfaceViewer.SetSurfaceRenderingMode[id, $Faceted, surfaceTool.sviewer];
3 => SurfaceViewer.SetSurfaceRenderingMode[id, $Smooth, surfaceTool.sviewer];
4 => SurfaceViewer.SetSurfaceRenderingMode[id, $HiddenLines, surfaceTool.sviewer];
5 => SurfaceViewer.SetSurfaceRenderingMode[id, $NormaledLines, surfaceTool.sviewer];
6 => SurfaceViewer.SetSurfaceRenderingMode[id, $ShadedLines, surfaceTool.sviewer];
ENDCASE => NULL;
END;
BugDir: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
ViewerTools.SetSelection[surfaceTool.activeState.dir];
END;
BugFile: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
ViewerTools.SetSelection[surfaceTool.activeState.filename];
END;
BugLoadSurface: Buttons.ButtonProc ~ BEGIN
Declarations
dir, file: Rope.ROPE;
scad: CADTypes.Scad;
id: NAT;
slot: NAT;
abort: BOOLEANFALSE;
Get a handle on the surface tool.
surfaceTool: SurfaceToolRef ← NARROW[clientData];
Decide which slot to use.
IF surfaceTool.activeState.surfaces[0].isLoaded = FALSE THEN slot ← 0
ELSE IF surfaceTool.activeState.surfaces[1].isLoaded = FALSE THEN slot ← 1
ELSE IF surfaceTool.activeState.surfaces[2].isLoaded = FALSE THEN slot ← 2
ELSE {FlashMessage["No more slots available."]; RETURN};
Read in the info file.
dir ← ViewerTools.GetContents[surfaceTool.activeState.dir];
file ← ViewerTools.GetContents[surfaceTool.activeState.filename];
scad ← CADIO.ReadInfoFile[Rope.Concat[dir, file]
! CADIO.Error => {FlashMessage["Error in Info file."]; abort ← TRUE; CONTINUE}
];
IF abort THEN RETURN;
Add it to the surface viewer context.
id ← SurfaceViewer.LoadSurface[scad, surfaceTool.sviewer
! SurfaceViewer.Error => {FlashMessage["SurfaceViewer raised error."]; abort ← TRUE; CONTINUE}
];
IF abort THEN RETURN;
Add it to the surface tool's active state.
surfaceTool.activeState.surfaces[slot].surfaceID ← id;
surfaceTool.activeState.surfaces[slot].isLoaded ← TRUE;
surfaceTool.activeState.surfaces[slot].cad ← scad;
surfaceTool.activeState.surfaces[slot].isVisible ← TRUE;
surfaceTool.activeState.surfaces[slot].mask ← NEW[CADTypes.VisibleMask[scad.cells.nCells]];
FOR i: NAT IN [0..scad.cells.nCells) DO
surfaceTool.activeState.surfaces[slot].mask[i] ← TRUE;
ENDLOOP;
surfaceTool.activeState.selectedSurface ← slot;
RepaintLetterButtons[surfaceTool];
RedrawEquationViewers[surfaceTool];
END;
BugStore: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
END;
BugHideAll: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
activeSurface: ActiveSurfaceRec ← surfaceTool.activeState.surfaces[surfaceTool.activeState.selectedSurface];
IF activeSurface.isLoaded = FALSE THEN BEGIN
FlashMessage["No selected surface"];
RETURN;
END;
FOR i: NAT IN [0..activeSurface.mask.length) DO
activeSurface.mask[i] ← FALSE;
ENDLOOP;
SurfaceViewer.MaskSurface[activeSurface.surfaceID, activeSurface.mask, surfaceTool.sviewer];
END;
BugHideOne: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
activeSurface: ActiveSurfaceRec ← surfaceTool.activeState.surfaces[surfaceTool.activeState.selectedSurface];
cellIndex: NAT;
IF activeSurface.isLoaded = FALSE THEN BEGIN
FlashMessage["No selected surface"];
RETURN;
END;
cellIndex ← CADIO.SelectCell[
activeSurface.cad,
activeSurface.mask,
"Select cell to hide"];
IF cellIndex # -1 THEN BEGIN
activeSurface.mask[cellIndex] ← FALSE;
SurfaceViewer.MaskSurface[activeSurface.surfaceID, activeSurface.mask, surfaceTool.sviewer];
END;
END;
BugRevealAll: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
activeSurface: ActiveSurfaceRec ← surfaceTool.activeState.surfaces[surfaceTool.activeState.selectedSurface];
selection: INT;
IF activeSurface.isLoaded = FALSE THEN BEGIN
FlashMessage["No selected surface"];
RETURN;
END;
selection ← 1;
selection ← PopUpMenu.RequestSelection[
label: "Options for Reveal",
choice: LIST [
"Reveal all cells",
"Reveal all 0-cells",
"Reveal all 1-cells",
"Reveal all 2-cells"
]
];
FOR i: NAT IN [0..activeSurface.mask.length) DO
SELECT selection FROM
1 => activeSurface.mask[i] ← TRUE;
2 => IF activeSurface.cad.cells[i].dimension = 0 THEN activeSurface.mask[i] ← TRUE;
3 => IF activeSurface.cad.cells[i].dimension = 1 THEN activeSurface.mask[i] ← TRUE;
4 => IF activeSurface.cad.cells[i].dimension = 2 THEN activeSurface.mask[i] ← TRUE;
ENDCASE;
ENDLOOP;
SurfaceViewer.MaskSurface[activeSurface.surfaceID, activeSurface.mask, surfaceTool.sviewer];
END;
BugRevealOne: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
activeSurface: ActiveSurfaceRec ← surfaceTool.activeState.surfaces[surfaceTool.activeState.selectedSurface];
cellIndex: INT;
IF activeSurface.isLoaded = FALSE THEN BEGIN
FlashMessage["No selected surface"];
RETURN;
END;
cellIndex ← CADIO.SelectCell[
activeSurface.cad,
activeSurface.mask,
"Select cell to reveal"];
IF cellIndex # -1 THEN BEGIN
activeSurface.mask[cellIndex] ← TRUE;
END;
SurfaceViewer.MaskSurface[activeSurface.surfaceID, activeSurface.mask, surfaceTool.sviewer];
END;
BugListAll: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
slot: NAT ← surfaceTool.activeState.selectedSurface;
IF surfaceTool.activeState.surfaces[slot].isLoaded = FALSE THEN BEGIN
FlashMessage["No selected surface"];
RETURN;
END;
[] ← CADIO.SelectCell[
surfaceTool.activeState.surfaces[slot].cad,
surfaceTool.activeState.surfaces[slot].mask,
"Cells"];
END;
Interpress subviewer
InterpressState: TYPE ~ RECORD [
dir: ViewerClasses.Viewer ← NIL,
file: ViewerClasses.Viewer ← NIL
];
BuildInterpressSubviewer: PROC [surfaceTool: SurfaceToolRef] ~ BEGIN
Formatting constants.
baseX: CARDINAL ~ 5;
baseY: CARDINAL ~ surfaceTool.height + verticalSpacingAboveSubviewer;
topRow: CARDINAL ~ baseY;
subRow: CARDINAL ~ topRow + verticalHeight;
firstRow: CARDINAL ~ subRow + smallVerticalSpacing;
bottomRow: CARDINAL ~ firstRow + verticalHeight + smallVerticalSpacing;
buttonWidth: CARDINAL ~ VFonts.StringWidth[" Do It "];
viewerWidth: CARDINAL ~ (toolWidth/2) - baseX - (buttonWidth*2);
doItColumn: CARDINAL ~ baseX;
dirButtonColumn: CARDINAL ~ doItColumn + buttonWidth + smallHorizontalSpacing;
dirViewerColumn: CARDINAL ~ dirButtonColumn + buttonWidth;
fileButtonColumn: CARDINAL ~ toolWidth / 2;
fileViewerColumn: CARDINAL ~ fileButtonColumn + buttonWidth;
title: Rope.ROPE ~ "Convert to Interpress";
titleColumn: CARDINAL ~ (toolWidth - VFonts.StringWidth[title])/2;
Declare the rules that will be built.
hrule1, hrule2, hrule3: Rules.Rule;
Build the title.
[] ← BuildLabel [title, surfaceTool.outer, titleColumn, topRow, TRUE];
Build the buttons and text viewers.
[] ← BuildButton [surfaceTool, "Do It", doItColumn, firstRow, BugDoIP, TRUE, buttonWidth];
[] ← BuildButton [surfaceTool, "Dir:", dirButtonColumn, firstRow, BugIPDir, TRUE, buttonWidth];
[] ← BuildButton [surfaceTool, "File:", fileButtonColumn, firstRow, BugIPFile, TRUE, buttonWidth];
surfaceTool.interpressState.dir ← BuildTextViewer [surfaceTool.outer, dirViewerColumn, firstRow, viewerWidth];
surfaceTool.interpressState.file ← BuildTextViewer [surfaceTool.outer, fileViewerColumn, firstRow, viewerWidth];
Fill in their defaults from the user profile.
ViewerTools.SetContents[surfaceTool.interpressState.dir, UserProfile.Token["AlgebraicSurfaces.Directory"]];
Draw the horizontal lines and constrain them to be the width of the tool.
hrule1 ← Rules.Create [[wx: 0, wy: topRow, wh: 1, parent: surfaceTool.outer]];
hrule2 ← Rules.Create [[wx: 0, wy: subRow, wh: 1, parent: surfaceTool.outer]];
hrule3 ← Rules.Create [[wx: 0, wy: bottomRow, wh: 1, parent: surfaceTool.outer]];
Containers.ChildXBound[surfaceTool.outer, hrule1];
Containers.ChildXBound[surfaceTool.outer, hrule2];
Containers.ChildXBound[surfaceTool.outer, hrule3];
Extend the tool's height.
surfaceTool.height ← surfaceTool.height + bottomRow - baseY + 1 + verticalSpacingBelowSubviewer;
END;
BugDoIP: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
dir: Rope.ROPE ← ViewerTools.GetContents[surfaceTool.interpressState.dir];
file: Rope.ROPE ← ViewerTools.GetContents[surfaceTool.interpressState.file];
ipFileName: Rope.ROPE ← Rope.Concat[dir, file];
message1: Rope.ROPE ← Rope.Cat["Writing interpress file ", ipFileName];
message2: Rope.ROPE ← Rope.Cat["File ", ipFileName, " written."];
MessageWindow.Append[message1, TRUE];
SurfaceViewer.ToInterpress[surfaceTool.sviewer, ipFileName];
MessageWindow.Append[message2, TRUE];
END;
BugIPDir: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
ViewerTools.SetSelection[surfaceTool.interpressState.dir];
END;
BugIPFile: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
ViewerTools.SetSelection[surfaceTool.interpressState.file];
END;
Ray tracer subviewer
RayTracerState: TYPE ~ RECORD [
variableX: ViewerClasses.Viewer ← NIL,
variableY: ViewerClasses.Viewer ← NIL,
variableZ: ViewerClasses.Viewer ← NIL,
widthInPixels: ViewerClasses.Viewer ← NIL,
heightInPixels: ViewerClasses.Viewer ← NIL,
dir: ViewerClasses.Viewer ← NIL,
filename: ViewerClasses.Viewer ← NIL
];
BuildRayTracerSubviewer: PROC [surfaceTool: SurfaceToolRef] ~ BEGIN
Formatting constants
baseX: CARDINAL ~ 5;
baseY: CARDINAL ~ surfaceTool.height + verticalSpacingAboveSubviewer;
title: Rope.ROPE ~ "Ray Tracer";
titleRow: CARDINAL ~ baseY;
titleColumn: CARDINAL ~ (toolWidth - VFonts.StringWidth[title])/2;
leftLabelColumn: CARDINAL ~ baseX;
varLabel: Rope.ROPE ~ "Variables: ";
sizeLabel: Rope.ROPE ~ "Size: ";
varViewerWidth: CARDINAL ~ VFonts.StringWidth[" Z "];
widthViewerWidth: CARDINAL ~ VFonts.StringWidth[" 256 "];
xViewerColumn: CARDINAL ~ leftLabelColumn + VFonts.StringWidth[varLabel];
yViewerColumn: CARDINAL ~ xViewerColumn + varViewerWidth;
zViewerColumn: CARDINAL ~ yViewerColumn + varViewerWidth;
widthViewerColumn: CARDINAL ~ leftLabelColumn + VFonts.StringWidth[varLabel];
byLabelColumn: CARDINAL ~ widthViewerColumn + widthViewerWidth;
heightViewerColumn: CARDINAL ~ byLabelColumn + widthViewerWidth + smallHorizontalSpacing;
rightLabelColumn: CARDINAL ~ toolWidth/2;
rightLabelWidth: CARDINAL ~ VFonts.StringWidth["Filename: "];
rightViewerWidth: CARDINAL ~ (toolWidth/2) - rightLabelWidth;
rightViewerColumn: CARDINAL ~ rightLabelColumn + rightLabelWidth + smallHorizontalSpacing;
doItWidth: CARDINAL ~ VFonts.StringWidth[" Do It "];
doItColumn: CARDINAL ~ toolWidth - doItWidth - smallHorizontalSpacing;
doItRow: CARDINAL ~ titleRow + smallVerticalSpacing;
firstRow: CARDINAL ~ titleRow + verticalHeight + smallVerticalSpacing;
secondRow: CARDINAL ~ firstRow + verticalHeight + smallVerticalSpacing;
bottomRow: CARDINAL ~ secondRow + verticalHeight + smallVerticalSpacing;
Declare the rules and buttons that will be built.
theBottomLine: Rules.Rule;
Build the title.
[] ← BuildLabel [title, surfaceTool.outer, titleColumn, titleRow, TRUE];
Build the left-hand labels and viewers.
[] ← BuildLabel [varLabel, surfaceTool.outer, leftLabelColumn, firstRow, FALSE];
[] ← BuildLabel [sizeLabel, surfaceTool.outer, leftLabelColumn, secondRow, FALSE];
surfaceTool.rayTracerState.variableX ← BuildTextViewer [surfaceTool.outer, xViewerColumn, firstRow, varViewerWidth];
surfaceTool.rayTracerState.variableY ← BuildTextViewer [surfaceTool.outer, yViewerColumn, firstRow, varViewerWidth];
surfaceTool.rayTracerState.variableZ ← BuildTextViewer [surfaceTool.outer, zViewerColumn, firstRow, varViewerWidth];
surfaceTool.rayTracerState.widthInPixels ← BuildTextViewer [surfaceTool.outer, widthViewerColumn, secondRow, widthViewerWidth];
[] ← BuildLabel ["by", surfaceTool.outer, byLabelColumn, secondRow, FALSE];
surfaceTool.rayTracerState.heightInPixels ← BuildTextViewer [surfaceTool.outer, heightViewerColumn, secondRow, widthViewerWidth];
Build the right-hand labels and viewers.
[] ← BuildLabel ["Dir: ", surfaceTool.outer, rightLabelColumn, firstRow, FALSE];
[] ← BuildLabel ["Filename: ", surfaceTool.outer, rightLabelColumn, secondRow, FALSE];
surfaceTool.rayTracerState.dir ← BuildTextViewer [surfaceTool.outer, rightViewerColumn, firstRow, rightViewerWidth];
surfaceTool.rayTracerState.filename ← BuildTextViewer [surfaceTool.outer, rightViewerColumn, secondRow, rightViewerWidth];
Build the Do It button.
[] ← BuildButton [surfaceTool, "Do It", doItColumn, doItRow, BugRayTrace, TRUE, doItWidth];
Fill in the defaults.
ViewerTools.SetContents[surfaceTool.rayTracerState.variableX, "x"];
ViewerTools.SetContents[surfaceTool.rayTracerState.variableY, "y"];
ViewerTools.SetContents[surfaceTool.rayTracerState.variableZ, "z"];
ViewerTools.SetContents[surfaceTool.rayTracerState.widthInPixels, "100"];
ViewerTools.SetContents[surfaceTool.rayTracerState.heightInPixels, "100"];
ViewerTools.SetContents[surfaceTool.rayTracerState.dir, UserProfile.Token["AlgebraicSurfaces.ImageDir"]];
Draw the bottom line and constrain it to be the width of the tool.
theBottomLine ← Rules.Create [[
wx: 0,
wy: bottomRow,
wh: 1,
parent: surfaceTool.outer]];
Containers.ChildXBound[surfaceTool.outer, theBottomLine];
Extend the tool's height.
surfaceTool.height ← surfaceTool.height + bottomRow - baseY + 1 + verticalSpacingBelowSubviewer;
END;
BugRayTrace: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
Get the contents of the various viewers.
varXRope: Rope.ROPE ← ViewerTools.GetContents[surfaceTool.rayTracerState.variableX];
varYRope: Rope.ROPE ← ViewerTools.GetContents[surfaceTool.rayTracerState.variableY];
varZRope: Rope.ROPE ← ViewerTools.GetContents[surfaceTool.rayTracerState.variableZ];
widthRope: Rope.ROPE ← ViewerTools.GetContents[surfaceTool.rayTracerState.widthInPixels];
heightRope: Rope.ROPE ← ViewerTools.GetContents[surfaceTool.rayTracerState.heightInPixels];
dir: Rope.ROPE ← ViewerTools.GetContents[surfaceTool.rayTracerState.dir];
filename: Rope.ROPE ← ViewerTools.GetContents[surfaceTool.rayTracerState.filename];
Convert them from ropes, flagging trouble if there is any.
varX, varY, varZ: ATOM;
width, height: CARDINAL;
trouble: BOOLEANFALSE;
IF Rope.Length[varXRope] # 1 OR Rope.Length[varYRope] # 1 OR Rope.Length[varZRope] # 1 THEN trouble ← TRUE;
varX ← Convert.AtomFromRope[varXRope
! Convert.Error => {trouble ← TRUE; CONTINUE}];
varY ← Convert.AtomFromRope[varYRope
! Convert.Error => {trouble ← TRUE; CONTINUE}];
varZ ← Convert.AtomFromRope[varZRope
! Convert.Error => {trouble ← TRUE; CONTINUE}];
width ← Convert.IntFromRope[widthRope
! Convert.Error => {trouble ← TRUE; CONTINUE}];
height ← Convert.IntFromRope[heightRope
! Convert.Error => {trouble ← TRUE; CONTINUE}];
IF width < 10 OR width > 255 OR height < 10 OR height > 255 THEN trouble ← TRUE;
IF trouble THEN {FlashMessage["Bad parameters; try again."]; RETURN};
Generate the image.
SurfaceViewer.InvokeRayTracer [
variables: [varX, varY, varZ],
filename: Rope.Concat[dir, filename],
pixelsU: height,
pixelsV: width,
sviewer: surfaceTool.sviewer
];
END;
Useful constructors.
BuildButton: PROC [surfaceTool: SurfaceToolRef, name: Rope.ROPE, column, row: CARDINAL, procedure: Buttons.ButtonProc, border: BOOLEAN, width: CARDINAL ← 0] RETURNS [button: Buttons.Button] ~ BEGIN
Builds a button which, when bugged, calls procedure. The button is labeled with name. If border is TRUE, the button has a border. If width is defaulted, the button's width will be sized to fit it.
IF width = 0 THEN
button ← Buttons.Create[
info: [
name: name,
wx: column,
wy: row,
wh: verticalHeight,
parent: surfaceTool.outer,
border: border],
proc: procedure,
clientData: surfaceTool]
ELSE
button ← Buttons.Create[
info: [
name: name,
wx: column,
wy: row,
wh: verticalHeight,
ww: width,
parent: surfaceTool.outer,
border: border],
proc: procedure,
clientData: surfaceTool]
END;
BuildDataLabel: PROC [parent: Containers.Container, column, row: CARDINAL] RETURNS [label: Labels.Label] ~ BEGIN
Builds a label which will be used to display a real number. Initially, the label contains the string "initialized".
label ← Labels.Create[[
name: "initializedwithanextremelylongishstring",
wx: column,
wy: row,
wh: verticalHeight,
ww: dataViewerWidth,
parent: parent,
border: FALSE]];
END;
BuildLabel: PROC [text: Rope.ROPE, parent: Containers.Container, column, row: CARDINAL, bold: BOOLEANFALSE] RETURNS [label: Labels.Label] ~ BEGIN
Build a label which will be used to display text.
fontFamily: Rope.ROPE = UserProfile.Token["DFTool.FontFamily", "Tioga"];
fontSize: NAT = UserProfile.Number["DFTool.FontSize", 10];
label ← Labels.Create[
info: [
name: text,
wx: column,
wy: row,
wh: verticalHeight,
ww: dataViewerWidth,
parent: parent,
border: FALSE],
font: VFonts.EstablishFont[family: fontFamily, size: fontSize, bold: bold] ];
END;
BuildTextViewer: PROC [parent: ViewerClasses.Viewer, column, row: CARDINAL, width: CARDINAL ← fileViewerWidth] RETURNS [ViewerClasses.Viewer] ~ BEGIN
RETURN [ViewerTools.MakeNewTextViewer[info: [
parent: parent,
wx: column,
wy: row,
wh: textViewerHeight,
ww: width,
border: FALSE,
scrollable: TRUE]]];
END;
RopeFromReal: PROC [from: REAL] RETURNS [result: Rope.ROPE] ~ BEGIN
Private conversion of real numbers into displayable ropes..
result ← IO.PutFR["%f", IO.real[from]];
END;
GetRealSelection: PROC [oldValue: REAL] RETURNS [value: REAL] ~ BEGIN
Converts whatever is selected into a real number. If converting the selection to a real causes an error, an error message is flashed in the message window and oldValue is returned.
selection: Rope.ROPE ← ViewerTools.GetSelectionContents[];
valid: BOOLEANTRUE;
selectedValue: REAL;
selectedValue ← Convert.RealFromRope[selection
! Convert.Error => {valid ← FALSE; CONTINUE};
];
IF valid THEN value ← selectedValue ELSE value ← oldValue;
END;
Other internal procedures.
LockButtons: PROC [surfaceTool: SurfaceToolRef] ~ BEGIN
surfaceTool.buttonsLocked ← TRUE;
END;
UnlockButtons: PROC [surfaceTool: SurfaceToolRef] ~ BEGIN
surfaceTool.buttonsLocked ← FALSE;
END;
FlashMessage: PROC [message: Rope.ROPE] ~ BEGIN
MessageWindow.Append[message, TRUE];
MessageWindow.Blink[];
END;
Define some CommandTool procedures.
OpenViewers: Commander.CommandProc ~ BEGIN
sviewer: REF SurfaceViewer.SurfaceViewer ← SurfaceViewer.CreateSurfaceViewer[];
MakeSurfaceTool[sviewer];
END;
OpenGrayViewers: Commander.CommandProc ~ BEGIN
sviewer: REF SurfaceViewer.SurfaceViewer ← SurfaceViewer.CreateSurfaceViewer[$ImagerGray];
MakeSurfaceTool[sviewer];
END;
Commander.Register[key: "ASViewers", proc: OpenViewers];
Commander.Register[key: "ASGrayViewers", proc: OpenGrayViewers];
END.