SurfaceToolImpl.mesa
James Rauen, July 3, 1986 10:27:31 pm PDT
July 14, 1986 5:20:47 pm PDT
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 [AtomFromRope, Error, IntFromRope, RealFromRope],
Icons USING [IconFlavor],
IO USING [real, PutFR],
Labels USING [Create, Label, Set],
Matrix3d USING [MakePureRotate, Matrix, Transform],
Menus USING [AppendMenuEntry, CreateEntry, CreateMenu, Menu, MenuEntry, MenuProc, SetGuarded],
MessageWindow USING [Append, Blink],
MultiPolynomial USING [RopeFromRef],
PopUpMenu USING [RequestSelection],
Rope USING [Concat, Length, ROPE],
Rules USING [Create, Rule],
SurfaceIcons USING [SurfaceToolIcon],
SurfaceViewer,
UserProfile USING [Number, Token],
Vector3d,
VFonts USING [CharWidth, EstablishFont, StringWidth],
ViewerClasses USING [Viewer],
ViewerOps USING [PaintViewer],
ViewerSpecs USING [openLeftWidth],
ViewerTools USING [GetContents, GetSelectionContents, MakeNewTextViewer, SetContents, SetSelection];
SurfaceToolImpl: CEDAR PROGRAM
IMPORTS Buttons, CADIO, Commander, Containers, Convert, IO, Labels, Matrix3d, Menus, MessageWindow, MultiPolynomial, PopUpMenu, Rope, Rules, SurfaceIcons, SurfaceViewer, UserProfile, Vector3d, VFonts, ViewerOps, ViewerSpecs, ViewerTools
~ BEGIN
Type declarations
SurfaceToolRef: TYPE ~ REF SurfaceToolRec;
SurfaceToolRec: TYPE ~ RECORD [
outer: Containers.Container ← NIL,
height: CARDINAL ← 0,
buttonsLocked: BOOLEANFALSE,
coordinates: CoordinateState,
conversionState: ConversionState,
positionState: PositionState,
orientationState: OrientationState,
activeState: ActiveState,
rayTracerState: RayTracerState];
MakeSurfaceTool: Commander.CommandProc ~ BEGIN
Declarations
surfaceTool: SurfaceToolRef ← NEW[SurfaceToolRec];
topMenu: Menus.Menu;
openEntry, viewEntry: Menus.MenuEntry;
Build the top menu
topMenu ← Menus.CreateMenu[];
openEntry ← Menus.CreateEntry["Open", BugOpen, surfaceTool];
viewEntry ← Menus.CreateEntry["View", BugView, surfaceTool];
Menus.AppendMenuEntry[topMenu, openEntry];
Menus.AppendMenuEntry[topMenu, viewEntry];
Menus.SetGuarded [openEntry, TRUE];
Create the tool
surfaceTool.outer ← Containers.Create[[
name: "Algebraic Surface Explorer",
icon: SurfaceIcons.SurfaceToolIcon[],
iconic: TRUE,
column: left,
menu: topMenu,
scrollable: FALSE]];
Add the subviewers
BuildPositionSubviewer[surfaceTool];
BuildActiveSubviewer[surfaceTool];
BuildRayTracerSubviewer[surfaceTool];
BuildConversionSubviewer[surfaceTool];
Paint it
ViewerOps.PaintViewer[surfaceTool.outer, all];
END;
SurfaceTool button procedures
BugOpen: Menus.MenuProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
SurfaceViewer.CreateSurfaceViewer[];
MakeNewFrame[surfaceTool];
END;
BugView: Menus.MenuProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
MakeNewFrame[surfaceTool];
END;
MakeNewFrame: PROC[surfaceTool: SurfaceToolRef] ~ BEGIN
Updates everything in the SurfaceViewer context, then draws a frame.
SurfaceViewer.ChangePosition[[
x: surfaceTool.positionState.position.x,
y: surfaceTool.positionState.position.y,
z: surfaceTool.positionState.position.z]];
SurfaceViewer.ChangeOrientation[
newForward: surfaceTool.orientationState.forward,
newUp: surfaceTool.orientationState.up];
SurfaceViewer.DrawFrame[];
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;
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 ~ 20;
baseY: CARDINAL ~ surfaceTool.height;
title: Rope.ROPE ~ "File Conversion";
titleRow: CARDINAL ~ baseY;
titleColumn: CARDINAL ~ (toolWidth - VFonts.StringWidth[title])/2;
buttonWidth: CARDINAL ~ VFonts.StringWidth["CAD: "];
viewerWidth: CARDINAL ~ (toolWidth/2) - baseX - buttonWidth;
sourceButtonColumn: CARDINAL ~ baseX;
sourceViewerColumn: CARDINAL ~ sourceButtonColumn + buttonWidth;
destButtonColumn: CARDINAL ~ toolWidth / 2;
destViewerColumn: CARDINAL ~ destButtonColumn + buttonWidth;
doItWidth: CARDINAL ~ VFonts.StringWidth[" Do It "];
doItColumn: CARDINAL ~ toolWidth - doItWidth - smallHorizontalSpacing;
doItRow: CARDINAL ~ titleRow + smallVerticalSpacing;
subtitleRow: CARDINAL ~ titleRow + verticalHeight + smallVerticalSpacing;
directoryRow: CARDINAL ~ subtitleRow + verticalHeight + smallVerticalSpacing;
fileRow: CARDINAL ~ directoryRow + verticalHeight + smallVerticalSpacing;
secondFileRow: CARDINAL ~ fileRow + verticalHeight + smallVerticalSpacing;
bottomRow: CARDINAL ~ secondFileRow + 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 labels.
[] ← BuildLabel ["Source files (CAD and Covering Set)", surfaceTool.outer, sourceButtonColumn, subtitleRow];
[] ← BuildLabel ["Destination file (Algebraic surface)", surfaceTool.outer, destButtonColumn, subtitleRow];
Build the buttons.
[] ← BuildButton [surfaceTool, "Dir:", sourceButtonColumn, directoryRow, BugSourceDir, FALSE, buttonWidth];
[] ← BuildButton [surfaceTool, "CAD:", sourceButtonColumn, fileRow, BugCadFile, FALSE, buttonWidth];
[] ← BuildButton [surfaceTool, "CS:", sourceButtonColumn, secondFileRow, BugCSFile, FALSE, buttonWidth];
[] ← BuildButton [surfaceTool, "Dir:", destButtonColumn, directoryRow, BugDestDir, FALSE, buttonWidth];
[] ← BuildButton [surfaceTool, "File:", destButtonColumn, fileRow, BugDestFile, FALSE, buttonWidth];
[] ← BuildButton [surfaceTool, "Do It", doItColumn, doItRow, BugConvert, TRUE, doItWidth];
Build the text viewers.
surfaceTool.conversionState.sourceDir ← BuildTextViewer [surfaceTool.outer, sourceViewerColumn, directoryRow, viewerWidth];
surfaceTool.conversionState.cadFile ← BuildTextViewer [surfaceTool.outer, sourceViewerColumn, fileRow, viewerWidth];
surfaceTool.conversionState.csFile ← BuildTextViewer [surfaceTool.outer, sourceViewerColumn, secondFileRow, viewerWidth];
surfaceTool.conversionState.destDir ← BuildTextViewer [surfaceTool.outer, destViewerColumn, directoryRow, viewerWidth];
surfaceTool.conversionState.destFile ← BuildTextViewer [surfaceTool.outer, destViewerColumn, fileRow, viewerWidth];
Fill in their defaults from the user profile.
ViewerTools.SetContents[surfaceTool.conversionState.sourceDir, UserProfile.Token["AlgebraicSurfaces.SourceDir"]];
ViewerTools.SetContents[surfaceTool.conversionState.destDir, UserProfile.Token["AlgebraicSurfaces.DestDir"]];
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;
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
PositionState: TYPE ~ RECORD [
position: Vector3d.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];
OrientationState: TYPE ~ RECORD [
forward: Vector3d.Triple ← [1, 0, 0],
up: Vector3d.Triple ← [0, 0, 1],
forwardXLabel: Labels.Label ← NIL,
forwardYLabel: Labels.Label ← NIL,
forwardZLabel: Labels.Label ← NIL,
upXLabel: Labels.Label ← NIL,
upYLabel: Labels.Label ← NIL,
upZLabel: Labels.Label ← NIL];
CoordinateState: TYPE ~ RECORD [
xVar: ATOM,
yVar: ATOM,
zVar: ATOM];
BuildPositionSubviewer: PROC [surfaceTool: SurfaceToolRef] ~ BEGIN
Formatting constants.
baseX: CARDINAL ~ 20;
baseY: CARDINAL ~ surfaceTool.height;
locationBlockX: CARDINAL ~ 20;
locationBlockY: CARDINAL ~ baseY;
locationTitleRow: CARDINAL ~ locationBlockY;
locationLongRuleRow: CARDINAL ~ locationSubtitleRow;
locationSubtitleRow: CARDINAL ~ locationTitleRow + verticalHeight + smallVerticalSpacing;
firstDataRow: CARDINAL ~ locationSubtitleRow + verticalHeight + smallVerticalSpacing;
secondDataRow: CARDINAL ~ firstDataRow + verticalHeight + smallVerticalSpacing;
thirdDataRow: CARDINAL ~ secondDataRow + verticalHeight + smallVerticalSpacing;
fourthRow: CARDINAL ~ thirdDataRow + verticalHeight + smallVerticalSpacing;
bottomRow: CARDINAL ~ fourthRow + verticalHeight + smallVerticalSpacing;
positionBlockX: CARDINAL ~ locationBlockX;
positionBlockY: CARDINAL ~ locationBlockY;
positionTitle: Rope.ROPE ~ "Position";
positionTitleRow: CARDINAL ~ locationTitleRow;
positionTitleColumn: CARDINAL ~ (positionEndColumn + positionBlockX - VFonts.StringWidth[positionTitle])/2;
positionPlusColumn: CARDINAL ~ positionBlockX;
positionMinusColumn: CARDINAL ~ positionBlockX + smallButtonWidth + smallHorizontalSpacing;
positionNewColumn: CARDINAL ~ positionMinusColumn + smallButtonWidth + smallHorizontalSpacing;
positionDataColumn: CARDINAL ~ positionNewColumn + dataButtonWidth;
positionEndColumn: CARDINAL ~ positionDataColumn + dataViewerWidth;
orientationBlockX: CARDINAL ~ positionEndColumn + smallHorizontalSpacing;
orientationBlockY: CARDINAL ~ locationBlockY;
orientationTitle: Rope.ROPE ~ "Orientation";
orientationTitleRow: CARDINAL ~ locationTitleRow;
orientationTitleColumn: CARDINAL ~ (orientationEndColumn + orientationBlockX - VFonts.StringWidth[orientationTitle])/2;
orientationLabelsColumn: CARDINAL ~ orientationBlockX;
orientationLeftColumn: CARDINAL ~ orientationLabelsColumn + 40;
orientationRightColumn: CARDINAL ~ orientationLeftColumn + 40;
orientationEndOfLabelsColumn: CARDINAL ~ orientationRightColumn + 40 + largeHorizontalSpacing;
orientationForwardTitle: Rope.ROPE ~ "Forward vector";
orientationForwardButtonColumn: CARDINAL ~ orientationEndOfLabelsColumn + largeHorizontalSpacing;
orientationForwardVectorColumn: CARDINAL ~ orientationForwardButtonColumn + smallButtonWidth + smallHorizontalSpacing;
orientationEndOfForwardColumn: CARDINAL ~ orientationForwardVectorColumn + dataViewerWidth + largeHorizontalSpacing;
orientationForwardTitleColumn: CARDINAL ~ (orientationEndOfForwardColumn + orientationEndOfLabelsColumn - VFonts.StringWidth[orientationForwardTitle])/2;
orientationUpTitle: Rope.ROPE ~ "Up vector";
orientationUpButtonColumn: CARDINAL ~ orientationEndOfForwardColumn + largeHorizontalSpacing;
orientationUpVectorColumn: CARDINAL ~ orientationUpButtonColumn + smallButtonWidth + smallHorizontalSpacing;
orientationEndOfUpColumn: CARDINAL ~ orientationUpVectorColumn + dataViewerWidth + largeHorizontalSpacing;
orientationUpTitleColumn: CARDINAL ~ (orientationEndOfUpColumn + orientationEndOfForwardColumn - VFonts.StringWidth[orientationUpTitle])/2;
orientationEndColumn: CARDINAL ~ orientationEndOfUpColumn;
orientationVectorTitleRow: CARDINAL ~ locationSubtitleRow;
bottomButtonWidth: CARDINAL ~ VFonts.StringWidth[" Backward "];
firstBottomButtonColumn: CARDINAL ~ locationBlockX;
secondBottomButtonColumn: CARDINAL ~ firstBottomButtonColumn + bottomButtonWidth;
thirdBottomButtonColumn: CARDINAL ~ secondBottomButtonColumn + bottomButtonWidth;
Declare the rules and buttons that will be built.
breakLine, horizontalLine, theBottomLine: Rules.Rule;
Orientation subtitles
forwardVectorTitle: Rope.ROPE ~ "Forward vector";
upVectorTitle: Rope.ROPE ~ "Up vector";
Build the position title.
[] ← BuildLabel [positionTitle, surfaceTool.outer, positionTitleColumn, positionTitleRow, TRUE];
Build the position buttons and labels.
[] ← BuildButton [surfaceTool, "+X", positionPlusColumn, firstDataRow, BugPlusX, TRUE, smallButtonWidth];
[] ← BuildButton [surfaceTool, "+Y", positionPlusColumn, secondDataRow, BugPlusY, TRUE, smallButtonWidth];
[] ← BuildButton [surfaceTool, "+Z", positionPlusColumn, thirdDataRow, BugPlusZ, TRUE, smallButtonWidth];
[] ← BuildButton [surfaceTool, "-X", positionMinusColumn, firstDataRow, BugMinusX, TRUE, smallButtonWidth];
[] ← BuildButton [surfaceTool, "-Y", positionMinusColumn, secondDataRow, BugMinusY, TRUE, smallButtonWidth];
[] ← BuildButton [surfaceTool, "-Z", positionMinusColumn, thirdDataRow, BugMinusZ, TRUE, smallButtonWidth];
[] ← BuildButton [surfaceTool, "x = ", positionNewColumn, firstDataRow, BugNewX, FALSE, smallButtonWidth];
[] ← BuildButton [surfaceTool, "y = ", positionNewColumn, secondDataRow, BugNewY, FALSE, smallButtonWidth];
[] ← BuildButton [surfaceTool, "z = ", positionNewColumn, thirdDataRow, BugNewZ, FALSE, smallButtonWidth];
surfaceTool.positionState.xDataLabel ←
BuildDataLabel [surfaceTool.outer, positionDataColumn, firstDataRow];
surfaceTool.positionState.yDataLabel ←
BuildDataLabel [surfaceTool.outer, positionDataColumn, secondDataRow];
surfaceTool.positionState.zDataLabel ←
BuildDataLabel [surfaceTool.outer, positionDataColumn, thirdDataRow];
Fill in the numbers.
UpdatePositionData[surfaceTool];
Build the orientation title.
[] ← BuildLabel [orientationTitle, surfaceTool.outer, orientationTitleColumn, orientationTitleRow, TRUE];
Build the Turn, Roll, and Dive labels and buttons.
[] ← Labels.Create[[name: "Turn", wx: orientationLabelsColumn, wy: firstDataRow, wh: verticalHeight, parent: surfaceTool.outer, border: FALSE]];
[] ← BuildButton[surfaceTool, "Left", orientationLeftColumn, firstDataRow, BugTurnLeft, TRUE];
[] ← BuildButton[surfaceTool, "Right", orientationRightColumn, firstDataRow, BugTurnRight, TRUE];
[] ← Labels.Create[[name: "Roll", wx: orientationLabelsColumn, wy: secondDataRow, wh: verticalHeight, parent: surfaceTool.outer, border: FALSE]];
[] ← BuildButton[surfaceTool, "Left", orientationLeftColumn, secondDataRow, BugRollLeft, TRUE];
[] ← BuildButton[surfaceTool, "Right", orientationRightColumn, secondDataRow, BugRollRight, TRUE];
[] ← Labels.Create[[name: "Dive", wx: orientationLabelsColumn, wy: thirdDataRow, wh: verticalHeight, parent: surfaceTool.outer, border: FALSE]];
[] ← BuildButton[surfaceTool, "Up", orientationLeftColumn, thirdDataRow, BugClimb, TRUE];
[] ← BuildButton[surfaceTool, "Down", orientationRightColumn, thirdDataRow, BugDive, TRUE];
Build the forward orientation vector labels and buttons.
[] ← BuildLabel[orientationForwardTitle, surfaceTool.outer, orientationForwardTitleColumn, orientationVectorTitleRow];
[] ← BuildButton[surfaceTool, "x = ", orientationForwardButtonColumn, firstDataRow, BugForwardX, FALSE, smallButtonWidth];
[] ← BuildButton[surfaceTool, "y = ", orientationForwardButtonColumn, secondDataRow, BugForwardY, FALSE, smallButtonWidth];
[] ← BuildButton[surfaceTool, "z = ", orientationForwardButtonColumn, thirdDataRow, BugForwardZ, FALSE, smallButtonWidth];
surfaceTool.orientationState.forwardXLabel ←
BuildDataLabel[surfaceTool.outer, orientationForwardVectorColumn, firstDataRow];
surfaceTool.orientationState.forwardYLabel ←
BuildDataLabel[surfaceTool.outer, orientationForwardVectorColumn, secondDataRow];
surfaceTool.orientationState.forwardZLabel ←
BuildDataLabel[surfaceTool.outer, orientationForwardVectorColumn, thirdDataRow];
Build the up orientation vector labels and buttons.
[] ← BuildLabel[orientationUpTitle, surfaceTool.outer, orientationUpTitleColumn, orientationVectorTitleRow];
[] ← BuildButton[surfaceTool, "x = ", orientationUpButtonColumn, firstDataRow, BugUpX, FALSE, smallButtonWidth];
[] ← BuildButton[surfaceTool, "y = ", orientationUpButtonColumn, secondDataRow, BugUpY, FALSE, smallButtonWidth];
[] ← BuildButton[surfaceTool, "z = ", orientationUpButtonColumn, thirdDataRow, BugUpZ, FALSE, smallButtonWidth];
surfaceTool.orientationState.upXLabel ←
BuildDataLabel[surfaceTool.outer, orientationUpVectorColumn, firstDataRow];
surfaceTool.orientationState.upYLabel ←
BuildDataLabel[surfaceTool.outer, orientationUpVectorColumn, secondDataRow];
surfaceTool.orientationState.upZLabel ←
BuildDataLabel[surfaceTool.outer, orientationUpVectorColumn, thirdDataRow];
Build the bottom row of buttons.
[] ← BuildButton[surfaceTool, "Forward", firstBottomButtonColumn, fourthRow, BugForward, TRUE];
[] ← BuildButton[surfaceTool, "Backward", secondBottomButtonColumn, fourthRow, BugBackward, TRUE];
[] ← BuildButton[surfaceTool, "Fancy maneuvers", thirdBottomButtonColumn, fourthRow, BugFancy, TRUE];
Fill in the numbers.
UpdateOrientationData[surfaceTool];
Draw the lines between the different orientation areas.
breakLine ← Rules.Create [[
wx: orientationEndOfLabelsColumn,
wy: orientationVectorTitleRow,
ww: 1,
wh: bottomRow - orientationVectorTitleRow,
parent: surfaceTool.outer]];
breakLine ← Rules.Create [[
wx: orientationEndOfForwardColumn,
wy: orientationVectorTitleRow,
ww: 1,
wh: bottomRow - orientationVectorTitleRow,
parent: surfaceTool.outer]];
Draw the horizontal lines and constrain them to be the width of the tool.
horizontalLine ← Rules.Create [[
wx: 0,
wy: orientationVectorTitleRow,
wh: 1,
parent: surfaceTool.outer]];
Containers.ChildXBound[surfaceTool.outer, horizontalLine];
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;
END;
UpdatePositionData: PROC[surfaceTool: SurfaceToolRef] ~ BEGIN
Update the x, y, and z data displays.
Labels.Set[surfaceTool.positionState.xDataLabel, RopeFromReal[surfaceTool.positionState.position.x]];
Labels.Set[surfaceTool.positionState.yDataLabel, RopeFromReal[surfaceTool.positionState.position.y]];
Labels.Set[surfaceTool.positionState.zDataLabel, RopeFromReal[surfaceTool.positionState.position.z]];
END;
UpdateOrientationData: PROC[surfaceTool: SurfaceToolRef] ~ BEGIN
Updates the orientation data displays.
Labels.Set[surfaceTool.orientationState.forwardXLabel, RopeFromReal[surfaceTool.orientationState.forward.x]];
Labels.Set[surfaceTool.orientationState.forwardYLabel, RopeFromReal[surfaceTool.orientationState.forward.y]];
Labels.Set[surfaceTool.orientationState.forwardZLabel, RopeFromReal[surfaceTool.orientationState.forward.z]];
Labels.Set[surfaceTool.orientationState.upXLabel, RopeFromReal[surfaceTool.orientationState.up.x]];
Labels.Set[surfaceTool.orientationState.upYLabel, RopeFromReal[surfaceTool.orientationState.up.y]];
Labels.Set[surfaceTool.orientationState.upZLabel, RopeFromReal[surfaceTool.orientationState.up.z]];
END;
BugPlusX: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
surfaceTool.positionState.position.x ← surfaceTool.positionState.position.x + surfaceTool.positionState.increment;
UpdatePositionData[surfaceTool];
END;
BugPlusY: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
surfaceTool.positionState.position.y ← surfaceTool.positionState.position.y + surfaceTool.positionState.increment;
UpdatePositionData[surfaceTool];
END;
BugPlusZ: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
surfaceTool.positionState.position.z ← surfaceTool.positionState.position.z + surfaceTool.positionState.increment;
UpdatePositionData[surfaceTool];
END;
BugMinusX: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
surfaceTool.positionState.position.x ← surfaceTool.positionState.position.x - surfaceTool.positionState.increment;
UpdatePositionData[surfaceTool];
END;
BugMinusY: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
surfaceTool.positionState.position.y ← surfaceTool.positionState.position.y - surfaceTool.positionState.increment;
UpdatePositionData[surfaceTool];
END;
BugMinusZ: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
surfaceTool.positionState.position.z ← surfaceTool.positionState.position.z - surfaceTool.positionState.increment;
UpdatePositionData[surfaceTool];
END;
BugNewX: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
value: REAL ← GetRealSelection[surfaceTool.positionState.position.x];
surfaceTool.positionState.position.x ← value;
UpdatePositionData[surfaceTool];
END;
BugNewY: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
value: REAL ← GetRealSelection[surfaceTool.positionState.position.y];
surfaceTool.positionState.position.y ← value;
UpdatePositionData[surfaceTool];
END;
BugNewZ: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
value: REAL ← GetRealSelection[surfaceTool.positionState.position.z];
surfaceTool.positionState.position.z ← value;
UpdatePositionData[surfaceTool];
END;
BugTurnLeft: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
axis: Vector3d.Triple ← surfaceTool.orientationState.up;
rotationMatrix: Matrix3d.Matrix ← Matrix3d.MakePureRotate[axis, -15];
oldForward: Vector3d.Triple ← surfaceTool.orientationState.forward;
newForward: Vector3d.Triple ← Matrix3d.Transform[oldForward, rotationMatrix];
surfaceTool.orientationState.forward ← newForward;
UpdateOrientationData[surfaceTool];
END;
BugTurnRight: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
axis: Vector3d.Triple ← surfaceTool.orientationState.up;
rotationMatrix: Matrix3d.Matrix ← Matrix3d.MakePureRotate[axis, 15];
oldForward: Vector3d.Triple ← surfaceTool.orientationState.forward;
newForward: Vector3d.Triple ← Matrix3d.Transform[oldForward, rotationMatrix];
surfaceTool.orientationState.forward ← newForward;
UpdateOrientationData[surfaceTool];
END;
BugRollLeft: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
axis: Vector3d.Triple ← surfaceTool.orientationState.forward;
rotationMatrix: Matrix3d.Matrix ← Matrix3d.MakePureRotate[axis, 15];
oldUp: Vector3d.Triple ← surfaceTool.orientationState.up;
newUp: Vector3d.Triple ← Matrix3d.Transform[oldUp, rotationMatrix];
surfaceTool.orientationState.up ← newUp;
UpdateOrientationData[surfaceTool];
END;
BugRollRight: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
axis: Vector3d.Triple ← surfaceTool.orientationState.forward;
rotationMatrix: Matrix3d.Matrix ← Matrix3d.MakePureRotate[axis, -15];
oldUp: Vector3d.Triple ← surfaceTool.orientationState.up;
newUp: Vector3d.Triple ← Matrix3d.Transform[oldUp, rotationMatrix];
surfaceTool.orientationState.up ← newUp;
UpdateOrientationData[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: Vector3d.Triple ← Vector3d.Cross[surfaceTool.orientationState.forward, surfaceTool.orientationState.up];
rotationMatrix: Matrix3d.Matrix ← Matrix3d.MakePureRotate[axis, -15];
oldUp: Vector3d.Triple ← surfaceTool.orientationState.up;
oldForward: Vector3d.Triple ← surfaceTool.orientationState.forward;
newUp: Vector3d.Triple ← Matrix3d.Transform[oldUp, rotationMatrix];
newForward: Vector3d.Triple ← Matrix3d.Transform[oldForward, rotationMatrix];
surfaceTool.orientationState.up ← newUp;
surfaceTool.orientationState.forward ← newForward;
UpdateOrientationData[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: Vector3d.Triple ← Vector3d.Cross[surfaceTool.orientationState.forward, surfaceTool.orientationState.up];
rotationMatrix: Matrix3d.Matrix ← Matrix3d.MakePureRotate[axis, 15];
oldUp: Vector3d.Triple ← surfaceTool.orientationState.up;
oldForward: Vector3d.Triple ← surfaceTool.orientationState.forward;
newUp: Vector3d.Triple ← Matrix3d.Transform[oldUp, rotationMatrix];
newForward: Vector3d.Triple ← Matrix3d.Transform[oldForward, rotationMatrix];
surfaceTool.orientationState.up ← newUp;
surfaceTool.orientationState.forward ← newForward;
UpdateOrientationData[surfaceTool];
END;
BugForwardX: Buttons.ButtonProc ~ BEGIN
END;
BugForwardY: Buttons.ButtonProc ~ BEGIN
END;
BugForwardZ: Buttons.ButtonProc ~ BEGIN
END;
BugUpX: Buttons.ButtonProc ~ BEGIN
END;
BugUpY: Buttons.ButtonProc ~ BEGIN
END;
BugUpZ: Buttons.ButtonProc ~ BEGIN
END;
BugForward: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
surfaceTool.positionState.position ← Vector3d.Add[surfaceTool.positionState.position, surfaceTool.orientationState.forward];
UpdatePositionData[surfaceTool];
UpdateOrientationData[surfaceTool];
END;
BugBackward: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
surfaceTool.positionState.position ← Vector3d.Sub[surfaceTool.positionState.position, surfaceTool.orientationState.forward];
UpdatePositionData[surfaceTool];
UpdateOrientationData[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"
];
selection: INT ← PopUpMenu.RequestSelection[
label: "Fancy maneuvers",
choice: options];
SELECT selection FROM
-1 => NULL; -- Timeout
0 => NULL; -- No selection
1 =>  -- Turn around
surfaceTool.orientationState.forward ← Vector3d.Mul[surfaceTool.orientationState.forward, -1];
2 => { -- Go to originB
surfaceTool.positionState.position ← [0, 0, 0];
};
3 => { -- Look towards origin
forward: Vector3d.Triple ← Vector3d.Neg[surfaceTool.positionState.position];
surfaceTool.orientationState.forward ← Vector3d.Normalize[forward];
surfaceTool.orientationState.up ← Vector3d.Ortho[forward, [1,0,0] ];
};
4 => { -- Look toward origin from +x axis
surfaceTool.positionState.position ← [10, 0, 0];
surfaceTool.orientationState.forward ← [-1, 0, 0];
surfaceTool.orientationState.up ← [0, 0, 1];
};
5 => { -- Look toward origin from +y axis
surfaceTool.positionState.position ← [0, 10, 0];
surfaceTool.orientationState.forward ← [0, -1, 0];
surfaceTool.orientationState.up ← [0, 0, 1];
};
6 => { -- Look toward origin from +z axis
surfaceTool.positionState.position ← [0, 0, 10];
surfaceTool.orientationState.forward ← [0, 0, -1];
surfaceTool.orientationState.up ← [0, 1, 0];
};
7 => { -- Look toward origin from -x axis
surfaceTool.positionState.position ← [-10, 0, 0];
surfaceTool.orientationState.forward ← [1, 0, 0];
surfaceTool.orientationState.up ← [0, 0, 1];
};
8 => { -- Look toward origin from -y axis
surfaceTool.positionState.position ← [0, -10, 0];
surfaceTool.orientationState.forward ← [0, 1, 0];
surfaceTool.orientationState.up ← [0, 0, 1];
};
9 => { -- Look toward origin from -z axis
surfaceTool.positionState.position ← [0, 0, -10];
surfaceTool.orientationState.forward ← [0, 0, 1];
surfaceTool.orientationState.up ← [0, 1, 0];
};
10 => { -- Look in +x direction
surfaceTool.orientationState.forward ← [1, 0, 0];
surfaceTool.orientationState.up ← [0, 0, 1];
};
11 => { -- Look in +y direction
surfaceTool.orientationState.forward ← [0, 1, 0];
surfaceTool.orientationState.up ← [0, 0, 1];
};
12 => { -- Look in +z direction
surfaceTool.orientationState.forward ← [0, 0, 1];
surfaceTool.orientationState.up ← [0, 1, 0];
};
ENDCASE => NULL;
UpdatePositionData[surfaceTool];
UpdateOrientationData[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 ~ 20;
baseY: CARDINAL ~ surfaceTool.height;
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 and buttons that will be built.
theBottomLine: 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, "Get color", activeSecondButtonColumn, activeCRow, BugGetColor, TRUE, activeSecondButtonWidth];
Build the directory and file buttons.
[] ← BuildButton [surfaceTool, "Working dir:", activeIOLabelColumn, activeDirRow, BugDir, FALSE, activeIOLabelWidth];
[] ← BuildButton [surfaceTool, "File name:", activeIOLabelColumn, activeFileRow, BugFile, FALSE, 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.ActiveDir"]];
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 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;
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.activeState.surfaces[selectedSurface].isLoaded ← FALSE;
RedrawEquationViewers[surfaceTool];
END;
END;
BugSetColor: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
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.activeState.surfaces[selectedSurface].isVisible ← FALSE;
END
ELSE BEGIN
SurfaceViewer.UnHideSurface [surfaceTool.activeState.surfaces[selectedSurface].surfaceID];
surfaceTool.activeState.surfaces[selectedSurface].isVisible ← TRUE;
END;
RedrawEquationViewers[surfaceTool];
MakeNewFrame[surfaceTool];
END;
END;
BugGetColor: Buttons.ButtonProc ~ BEGIN
surfaceTool: SurfaceToolRef ← NARROW[clientData];
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
! 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];
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];
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 ← 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];
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];
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;
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 ~ 20;
baseY: CARDINAL ~ surfaceTool.height;
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;
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
];
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;
Commander.Register[key: "SurfaceTool", proc: MakeSurfaceTool];
END.