File: SVViewerUserImplB.mesa
Author: Eric Bier in October 1982
Copyright © 1984 by Xerox Corporation. All rights reserved.
Last edited by Bier on January 26, 1985 10:57:07 pm PST
Contents: Code to respond to button presses made in an SVViewer
DIRECTORY
AIS,
BasicTime,
Buttons,
CastRays,
CGDevice,
ColorMap,
Containers,
CoordSys,
CSG,
CSGGraphics,
DisplayList3d,
DisplayListToTree,
DisplayMap,
DitherAIS,
FS,
Graphics,
GraphicsBasic,
GraphicsColor,
GraphicsToPress,
InputFocus,
IO,
Labels,
Menus,
MessageWindow,
Preprocess3d,
Real,
Rope,
SV2d,
SV3d,
SVBoundBox,
SVDraw3d,
SVEditUser,
SVError,
SVFileoutPoly,
SVFiles,
SVImage,
SVInterfaceTypes,
SVModelTypes,
SVRayTypes,
SVSceneTypes,
SVSelections,
SVSlices,
SVTransforms,
SVViewerTool,
SVViewerTools,
SVViewerUser,
TFO3d,
ViewerClasses,
ViewerTools;
SVViewerUserImplB:
CEDAR
PROGRAM
IMPORTS AIS, BasicTime, Buttons, CastRays, ColorMap, CoordSys, CSG, CSGGraphics, DisplayList3d, DisplayListToTree, DisplayMap, DitherAIS, FS, Graphics, GraphicsToPress, InputFocus, IO, Labels, MessageWindow, Preprocess3d, Real, Rope, SVBoundBox, SVDraw3d, SVEditUser, SVError, SVFiles, SVFileoutPoly, SVImage, SVSelections, SVSlices, SVViewerUser, SVViewerTools, TFO3d, ViewerTools
EXPORTS GraphicsBasic, SVViewerUser =
BEGIN
Assembly: TYPE = SVSceneTypes.Assembly;
BoundBox: TYPE = SVModelTypes.BoundBox;
Camera: TYPE = SVModelTypes.Camera;
Classification: TYPE = SVRayTypes.Classification;
Color: TYPE = GraphicsColor.Color;
CoordSysGenerator: TYPE = DisplayList3d.CoordSysGenerator;
CSGTree: TYPE = SVRayTypes.CSGTree;
DeviceObject: PUBLIC TYPE = CGDevice.Rep;
DrawStyle: TYPE = SVModelTypes.DrawStyle;
EditToolData: TYPE = SVEditUser.EditToolData;
FrameBox: TYPE = SVModelTypes.FrameBox;
MasterObject: TYPE = SVSceneTypes.MasterObject;
Matrix4by4: TYPE = SV3d.Matrix4by4;
MouseButton: TYPE = Menus.MouseButton;
Point2d: TYPE = SV2d.Point2d;
Primitive: TYPE = SVRayTypes.Primitive;
Ray: TYPE = SVRayTypes.Ray;
Scene: TYPE = SVSceneTypes.Scene;
Selection: TYPE = SVInterfaceTypes.Selection;
SelectionType: TYPE = SVInterfaceTypes.SelectionType;
Slice: TYPE = SVSlices.Slice;
Vector: TYPE = SV3d.Vector;
Viewer: TYPE = ViewerClasses.Viewer;
ViewerToolData: TYPE = SVInterfaceTypes.ViewerToolData;
DCProc: TYPE = SVInterfaceTypes.DCProc;
globalTable: DisplayMap.ColorTable;
globalSceneStyleCount: NAT = 3;
globalSceneStyleArray:
ARRAY[1..globalSceneStyleCount]
OF Rope.
ROPE ←
["WireFrame", "Shaded", "Normals"];
Press:
PUBLIC
PROC [parent:
REF
ANY, clientData:
REF
ANY, mouseButton: MouseButton, shift, control:
BOOL] =
TRUSTED {
viewerToolData: ViewerToolData ← NARROW[clientData];
camera: Camera ← viewerToolData.camera;
TIMING VARABLES
startTime: BasicTime.GMT;
endTime: BasicTime.GMT;
totalTime: INT;
timeRope: Rope.ROPE;
PRESS VARIABLES
pressName: Rope.ROPE;
pressContext: Graphics.Context;
START TIMING
pressName ← ViewerTools.GetContents[viewerToolData.textSection.ais];
pressName ← Rope.Concat[SVFiles.FilenameMinusExtension[pressName], ".press"];
SVError.Append[Rope.Cat["Pressing ", pressName, "... "], TRUE];
startTime ← BasicTime.Now[];
START PRESSING
pressContext ← GraphicsToPress.NewContext[pressName];
CSGGraphics.Clip[pressContext, camera];
CSGGraphics.SetQualityCamera[camera, quality]; -- make a high quality image
CSGGraphics.ColorFilmCamera[camera, FALSE]; -- but only black and white
SVViewerUser.DrawSceneEtc[pressContext, viewerToolData, TRUE];
CSGGraphics.ColorFilmCamera[camera, TRUE]; -- restore to color mode
CSGGraphics.SetQualityCamera[camera, fast]; -- restore to fast mode for interactive editting
GraphicsToPress.Close[pressContext];
END TIMING
endTime ← BasicTime.Now[];
totalTime ← BasicTime.Period[startTime, endTime];
timeRope ← IO.PutFR[" Done making %g. Pressing took (%r)", [rope[pressName]], [integer[totalTime]]];
SVError.Append[timeRope, FALSE, TRUE];
};
PressAIS:
PUBLIC
PROC [parent:
REF
ANY, clientData:
REF
ANY, mouseButton: MouseButton, shift, control:
BOOL] =
TRUSTED {
viewerToolData: ViewerToolData ← NARROW[clientData];
scene: Scene ← viewerToolData.scene;
camera: Camera ← viewerToolData.camera;
minX, minY, maxX, maxY: REAL;
tree: CSGTree;
aisRope: Rope.ROPE ← ViewerTools.GetContents[viewerToolData.textSection.ais];
TIMING VARABLES
startTime: BasicTime.GMT;
endTime: BasicTime.GMT;
totalTime: INT;
timeRope: Rope.ROPE;
PRESS VARIABLES
pressName: Rope.ROPE;
pressStream: IO.STREAM;
pressContext: Graphics.Context;
START TIMING
startTime ← BasicTime.Now[];
START PRESSING
pressName ← ViewerTools.GetContents[viewerToolData.textSection.ais];
pressName ← Rope.Concat[SVFiles.FilenameMinusExtension[pressName], ".press"];
pressStream ← FS.StreamOpen[pressName, $create];
pressContext ← GraphicsToPress.NewContextFromStream[
outputStream: pressStream,
fileNameForHeaderPage: pressName,
resolution: 384];
tree ← DisplayListToTree.AssemblyToTree[scene.assembly, scene, camera];
[minX, minY, maxX, maxY] ← MinAndMaxFromCameraAndTree[camera, tree];
SVImage.DrawAndScaleColorImage[pressContext, aisRope, [camera.screenCS.mat[1][4], camera.screenCS.mat[2][4]], minX, minY, maxX, maxY];
GraphicsToPress.Close[pressContext];
endTime ← BasicTime.Now[];
totalTime ← BasicTime.Period[startTime, endTime];
timeRope ← IO.PutFR[" Done. Pressing AIS took (%r)",[integer[totalTime]]];
SVError.Append[timeRope, TRUE, TRUE];
};
PressBWAIS: PUBLIC PROC [parent: REF ANY, clientData: REF ANY, mouseButton: MouseButton, shift, control: BOOL] = TRUSTED {
viewerToolData: ViewerToolData ← NARROW[clientData];
editToolData: EditToolData ← NARROW[viewerToolData.editToolData];
scene: Scene ← viewerToolData.scene;
camera: Camera ← viewerToolData.camera;
minX, minY, maxX, maxY: REAL;
tree: CSGTree;
aisRope: Rope.ROPE ← ViewerTools.GetContents[viewerToolData.textSection.ais];
TIMING VARABLES
startTime: BasicTime.GMT;
endTime: BasicTime.GMT;
totalTime: INT;
timeRope: Rope.ROPE;
PRESS VARIABLES
pressName: Rope.ROPE;
pressStream: IO.STREAM;
pressContext: Graphics.Context;
START TIMING
startTime ← BasicTime.Now[];
START PRESSING
pressName ← ViewerTools.GetContents[viewerToolData.textSection.ais];
pressName ← Rope.Concat[SVFiles.FilenameMinusExtension[pressName], ".press"];
pressStream ← FS.StreamOpen[pressName, $create];
pressContext ← GraphicsToPress.NewContextFromStream[
outputStream: pressStream,
fileNameForHeaderPage: pressName,
resolution: 384];
tree ← DisplayList3d.SceneToTree[scene, camera];
[minX, minY, maxX, maxY] ← MinAndMaxFromCameraAndTree[camera, tree];
SVImage.DrawAndScaleBlackAndWhiteImage[pressContext, aisRope, [camera.screenCS.mat[1][4], camera.screenCS.mat[2][4]], minX, minY, maxX, maxY];
GraphicsToPress.Close[pressContext];
endTime ← BasicTime.Now[];
totalTime ← BasicTime.Period[startTime, endTime];
timeRope ← IO.PutFR[" Done. Pressing AIS took (%r)",[integer[totalTime]]];
SVError.Append[timeRope, TRUE, TRUE];
};
StorePoly:
PUBLIC
PROC [parent:
REF
ANY, clientData:
REF
ANY, mouseButton: MouseButton, shift, control:
BOOL] =
TRUSTED {
viewerToolData: ViewerToolData ← NARROW[clientData];
editToolData: EditToolData ← NARROW[viewerToolData.editToolData];
wdir: Rope.ROPE;
success, confirmation: BOOL;
f: IO.STREAM;
picName: Rope.ROPE ← ViewerTools.GetSelectionContents[];
fullName: Rope.ROPE;
scene: Scene ← viewerToolData.scene;
IF Rope.Length[picName] = 0 THEN RETURN;
wdir ← editToolData.originalWorkingDirectory;
success ← TRUE;
[fullName,,] ←
FS.ExpandName[picName, wdir
!
FS.Error =>
IF error.group = user
THEN {
success ← FALSE;
CONTINUE;
}
];
IF NOT success THEN RETURN;
IF SVFiles.FileExists[fullName]
THEN {
confirmation ← MessageWindow.Confirm["Confirm overwrite of existing pic file"];
IF confirmation
THEN
f ← FS.StreamOpen[fullName, $create]
ELSE RETURN;
}
ELSE f ← FS.StreamOpen[fullName, $create];
SVError.Append["Writing scene: ",TRUE];
SVError.Append[fullName];
SVError.Append[" to file: "];
SVError.Append[fullName];
SVError.Append["..."];
IF NOT success THEN RETURN;
SVFileoutPoly.StorePolyScene[scene, f, fullName];
SVError.Append["Done"];
}; -- end of StorePoly
CrossHairs:
PUBLIC
PROC [parent:
REF
ANY, clientData:
REF
ANY, mouseButton: MouseButton, shift, control:
BOOL] =
TRUSTED {
viewer is the crossHairs button
viewerToolData: ViewerToolData ← NARROW[clientData];
camera: Camera ← viewerToolData.camera;
DoCrossHairs:
PROC [dc: Graphics.Context] =
TRUSTED {
SVDraw3d.Draw2dCoordSys[dc, [0,0], camera];
};
SVViewerUser.Painter[DoCrossHairs, viewerToolData];
}; -- end of CrossHairs
Dither:
PUBLIC
PROC [parent:
REF
ANY, clientData:
REF
ANY, mouseButton: MouseButton, shift, control:
BOOL] =
TRUSTED {
viewerToolData: ViewerToolData ← NARROW[clientData];
baseName, redName, greenName, blueName, FSFilename: Rope.ROPE;
baseName ← ViewerTools.GetContents[viewerToolData.textSection.ais];
baseName ← SVFiles.FilenameMinusExtension[baseName];
redName ← Rope.Concat[baseName, "-red.ais"];
greenName ← Rope.Concat[baseName, "-grn.ais"];
blueName ← Rope.Concat[baseName, "-blu.ais"];
FSFilename ← Rope.Concat[baseName, "-std.ais"];
BEGIN
globalTable ← Preprocess3d.GetGlobalTable[];
DitherAIS.Squash[redName, greenName, blueName, FSFilename, MyMap
!
AIS.Error =>
TRUSTED {
msgRope: Rope.ROPE;
msgRope ← IO.PutFR["%g -*.ais - Bad file names", [rope[baseName]]];
SVError.Append[Rope.Concat[baseName, "-*.ais - Bad file names"], TRUE, TRUE];
GOTO giveUp}];
If the dither has worked, fake a button press of DrawDither:
DrawDither[parent, clientData, mouseButton, shift, control];
END;
};
MyMap: DitherAIS.UserMapProc =
TRUSTED {
rb, gb, bb: DisplayMap.ColorMapSize;
palix ← DisplayMap.GetIndex[r, g, b, globalTable];
[rb, gb, bb] ← ColorMap.GetColor[palix]; -- ought to use the table
re ← r - rb;
ge ← g - gb;
be ← b - bb;
};
Move: PUBLIC PROC [parent: REF ANY, clientData: REF ANY, mouseButton: MouseButton, shift, control: BOOL] = TRUSTED {
newMat: Matrix4by4;
target, movee: Selection;
target ← SVEditUser.GetTargetSelection[];
movee ← SVEditUser.GetMoveeSelection[];
IF target = NIL THEN ERROR;
IF target.assembly = NIL THEN RETURN;
IF movee = NIL THEN ERROR;
IF movee.assembly = NIL THEN RETURN;
If the two selections are in different viewers, then see if these viewers refer to different scenes. If so do a scene to scene copy before doing any aligning and abutting.
IF target.viewerToolData # movee.viewerToolData THEN {
targetPicture: ViewerPictureData ← NARROW[target.viewerToolData.viewerPicture.data];
moveePicture: ViewerPictureData ← NARROW[movee.viewerToolData.viewerPicture.data];
IF targetPicture.scene # moveePicture.scene THEN {
copyAssembly: Assembly ← DisplayList3d.MergeAssemblyIntoScene[movee.assembly, moveePicture.scene, targetPicture.scene.assembly, targetPicture.scene];
The new assembly has the same relationship to scene assembly as the last assembly had to its parent. This will do for now.
SVViewerUser.SceneNewVersion[target.viewerToolData];
SVViewerUser.DrawSceneInternal[NIL, target.viewerToolData, red, FALSE, FALSE];
SVViewerUser.DrawSceneInternal[NIL, movee.viewerToolData, red, FALSE, FALSE];
RETURN;
};
};
newMat ← Matrix3d.MakeRotateYMat[180];
SVTransforms.TugTransf[movee.assembly.coordSys, movee.coordSys, target.coordSys, newMat];
Rotate them so they are tangent in an exterior fashion.
SVViewerUser.SceneNewVersion[target.viewerToolData];
SVViewerUser.DrawSceneInternal[NIL, target.viewerToolData, red, FALSE, FALSE];
};
DrawPt:
PUBLIC
PROC [parent:
REF
ANY, clientData:
REF
ANY, mouseButton: MouseButton, shift, control:
BOOL] =
TRUSTED {
viewerToolData: ViewerToolData ← NARROW[clientData];
camera: Camera ← viewerToolData.camera;
get x and y from appropriate slots. Interpret this as camera coordinates and draw a cross.
x, y: REAL;
DoDrawPt:
PROC [dc: Graphics.Context] =
TRUSTED {
SVDraw3d.DrawX[dc, [x, y], camera];
};
[x, y] ← SVViewerUser.ReadTwoReals[viewerToolData.textSection.xyz];
SVViewerUser.Painter[DoDrawPt, viewerToolData];
};
MinAndMaxFromCameraAndTree:
PRIVATE
PROC [camera: Camera, tree: CSGTree]
RETURNS [minX, minY, maxX, maxY:
REAL] =
TRUSTED {
frame: FrameBox ← camera.frame;
boundBox: BoundBox;
defaultHalfSide: REAL = 100.0;
IF frame.fullScreen
THEN {
[boundBox] ← Preprocess3d.PreprocessForInteraction[tree, camera];
IF boundBox =
NIL
THEN {
minX ← minY ← -defaultHalfSide;
maxX ← maxY ← defaultHalfSide;
}
ELSE {
minX ← boundBox.minVert[1]; minY ← boundBox.minVert[2];
maxX ← boundBox.maxVert[1]; maxY ← boundBox.maxVert[2];
};
}
ELSE {
minX ← frame.downLeft[1]; minY ← frame.downLeft[2];
maxX ← frame.upRight[1]; maxY ← frame.upRight[2];
};
};
DrawColor:
PUBLIC
PROC [parent:
REF
ANY, clientData:
REF
ANY, mouseButton: MouseButton, shift, control:
BOOL] =
TRUSTED {
parent is the DrawColor button
viewerToolData: ViewerToolData ← NARROW[clientData];
scene: Scene ← viewerToolData.scene;
resolution: REAL;
boundBox: BoundBox;
minX, minY, maxX, maxY: REAL;
camera: Camera ← viewerToolData.camera;
tree: CSGTree;
aisRope: Rope.ROPE ← ViewerTools.GetContents[viewerToolData.textSection.ais];
DoDrawColor:
PROC [dc: Graphics.Context] =
TRUSTED {
SVImage.DrawAlignedColorImage[dc, aisRope, resolution, [camera.screenCS.mat[1][4], camera.screenCS.mat[2][4]], boundBox];
};
resolution ← camera.resolution;
tree ← DisplayListToTree.AssemblyToTree[scene.assembly, scene, camera];
[minX, minY, maxX, maxY] ← MinAndMaxFromCameraAndTree[camera, tree];
boundBox ← SVBoundBox.BoundBoxFromValues[minX, minY, maxX, maxY];
SVViewerUser.Painter[DoDrawColor, viewerToolData];
}; -- end of DrawColor
DrawBlackAndWhite:
PUBLIC
PROC [parent:
REF
ANY, clientData:
REF
ANY, mouseButton: MouseButton, shift, control:
BOOL] =
TRUSTED {
parent is the DrawB&W button
viewerToolData: ViewerToolData ← NARROW[clientData];
resolution: REAL;
scene: Scene ← viewerToolData.scene;
boundBox: BoundBox;
minX, minY, maxX, maxY: REAL;
camera: Camera ← viewerToolData.camera;
tree: CSGTree;
oldMode: Graphics.PaintMode;
aisRope: Rope.ROPE ← ViewerTools.GetContents[viewerToolData.textSection.ais];
DoDrawBlackAndWhite:
PROC [dc: Graphics.Context] =
TRUSTED {
SVImage.DrawAlignedBlackAndWhiteImage[dc, aisRope, resolution, [camera.screenCS.mat[1][4], camera.screenCS.mat[2][4]], boundBox, FALSE];
};
DoDrawFrame:
SAFE
PROC [dc: Graphics.Context] =
TRUSTED {
Graphics.SetColor[dc, GraphicsColor.black];
oldMode ← Graphics.SetPaintMode[dc, invert];
CSGGraphics.DrawFrame [dc, camera];
[] ← Graphics.SetPaintMode[dc, oldMode];
};
resolution ← camera.resolution;
tree ← DisplayListToTree.AssemblyToTree[scene.assembly, scene, camera];
[minX, minY, maxX, maxY] ← MinAndMaxFromCameraAndTree[camera, tree];
boundBox ← SVBoundBox.BoundBoxFromValues[minX, minY, maxX, maxY];
SVViewerUser.Painter[DoDrawBlackAndWhite, viewerToolData];
SVViewerUser.Painter[DoDrawFrame, viewerToolData]; -- redraw frame
}; -- end of DrawBlackAndWhite
DrawDither:
PUBLIC
PROC [parent:
REF
ANY, clientData:
REF
ANY, mouseButton: MouseButton, shift, control:
BOOL] =
TRUSTED {
parent is the DrawDither button
viewerToolData: ViewerToolData ← NARROW[clientData];
resolution: REAL;
scene: Scene ← viewerToolData.scene;
boundBox: BoundBox;
minX, minY, maxX, maxY: REAL;
camera: Camera ← viewerToolData.camera;
tree: CSGTree;
aisRope: Rope.ROPE ← ViewerTools.GetContents[viewerToolData.textSection.ais];
DoDrawBlackAndWhite:
PROC [dc: Graphics.Context] =
TRUSTED {
SVImage.DrawAlignedBlackAndWhiteImage[dc, aisRope, resolution, [camera.screenCS.mat[1][4], camera.screenCS.mat[2][4]], boundBox, TRUE];
};
resolution ← camera.resolution;
aisRope ← Rope.Concat[SVFiles.FilenameMinusExtension[aisRope], "-std.ais"];
tree ← DisplayListToTree.AssemblyToTree[scene.assembly, scene, camera];
[minX, minY, maxX, maxY] ← MinAndMaxFromCameraAndTree[camera, tree];
boundBox ← SVBoundBox.BoundBoxFromValues[minX, minY, maxX, maxY];
SVViewerUser.Painter[DoDrawBlackAndWhite, viewerToolData];
}; -- end of DrawDither
SetFocalLength:
PUBLIC
PROC [parent:
REF
ANY, clientData:
REF
ANY, mouseButton: MouseButton, shift, control:
BOOL] =
TRUSTED {
viewerToolData: ViewerToolData ← NARROW[clientData];
viewerToolData.camera.focalLength ← SVViewerTools.GetReal[viewerToolData.textSection.focalLength, 1800];
}; -- end of SetFocalLength
PROMPTS
AISPrompt:
PUBLIC
PROC [parent:
REF
ANY, clientData:
REF
ANY, mouseButton: MouseButton, shift, control:
BOOL] =
TRUSTED {
viewerToolData: ViewerToolData ← NARROW[clientData];
ViewerTools.SetSelection[viewerToolData.textSection.ais];
};
XYZPrompt:
PUBLIC
PROC [parent:
REF
ANY, clientData:
REF
ANY, mouseButton: MouseButton, shift, control:
BOOL] =
TRUSTED {
viewerToolData: ViewerToolData ← NARROW[clientData];
ViewerTools.SetSelection[viewerToolData.textSection.xyz];
};
FocalLengthPrompt:
PUBLIC
PROC [parent:
REF
ANY, clientData:
REF
ANY, mouseButton: MouseButton, shift, control:
BOOL] =
TRUSTED {
viewerToolData: ViewerToolData ← NARROW[clientData];
ViewerTools.SetSelection[viewerToolData.textSection.focalLength];
};
TextPrompt:
PUBLIC
PROC [parent:
REF
ANY, clientData:
REF
ANY, mouseButton: MouseButton, shift, control:
BOOL] =
TRUSTED {
viewerToolData: ViewerToolData ← NARROW[clientData];
ViewerTools.SetSelection[viewerToolData.textSection.text];
};
PROMPTS WHICH CYCLE THROUGH POSSIBILITIES
StylePrompt:
PUBLIC
PROC [parent:
REF
ANY, clientData:
REF
ANY, mouseButton: MouseButton, shift, control:
BOOL] =
TRUSTED {
viewerToolData: ViewerToolData ← NARROW[clientData];
newStyle: DrawStyle;
scene: Scene ← viewerToolData.scene;
viewerToolData.sceneStyleIndex ← IF viewerToolData.sceneStyleIndex = globalSceneStyleCount THEN 1 ELSE viewerToolData.sceneStyleIndex + 1;
Labels.Set[viewerToolData.textSection.viewStyle, globalSceneStyleArray[viewerToolData.sceneStyleIndex]];
SELECT globalSceneStyleArray[viewerToolData.sceneStyleIndex]
FROM
"WireFrame" => newStyle ← wire;
"Shaded" => newStyle ← shaded;
"Normals" => newStyle ← normals;
"RayCast" => newStyle ← rayCast;
ENDCASE => ERROR;
viewerToolData.camera.style ← newStyle;
};
ON/OFF SWITCHES
DoubleBuffer:
PUBLIC
PROC [parent:
REF
ANY, clientData:
REF
ANY, mouseButton: MouseButton, shift, control:
BOOL] =
TRUSTED {
button: Buttons.Button ← NARROW[parent];
viewerToolData: ViewerToolData ← NARROW[clientData];
IF viewerToolData.doubleBuffer
THEN {
viewerToolData.doubleBuffer ← NOT viewerToolData.doubleBuffer;
Buttons.SetDisplayStyle[button, $BlackOnWhite];
}
ELSE {
viewerToolData.doubleBuffer ← NOT viewerToolData.doubleBuffer;
Buttons.SetDisplayStyle[button, $WhiteOnBlack];
};
}; -- end of DoubleBuffer
ShowCoordsMode:
PUBLIC
PROC [parent:
REF
ANY, clientData:
REF
ANY, mouseButton: MouseButton, shift, control:
BOOL] =
TRUSTED {
button: Buttons.Button ← NARROW[parent];
viewerToolData: ViewerToolData ← NARROW[clientData];
IF viewerToolData.showCoordSys
THEN {
viewerToolData.showCoordSys ← NOT viewerToolData.showCoordSys;
Buttons.SetDisplayStyle[button, $BlackOnWhite];
}
ELSE {
viewerToolData.showCoordSys ← NOT viewerToolData.showCoordSys;
Buttons.SetDisplayStyle[button, $WhiteOnBlack];
};
}; -- end of ShowCoordsMode
UTILITIES
Selected:
PUBLIC
PROC [parent:
REF
ANY, clientData:
REF
ANY, mouseButton: MouseButton, shift, control:
BOOL] =
TRUSTED {
This window has been selected. Show its Selected button as WhiteOnBlack.
viewerToolData: ViewerToolData ← NARROW[clientData];
solidViewer: Viewer ← viewerToolData.viewerPicture;
InputFocus.SetInputFocus[solidViewer];
SVEditUser.ReSelectViewer[viewerToolData];
};
Deselected:
PUBLIC
PROC [viewerToolData: ViewerToolData] =
TRUSTED {
This window has been deselected. Show its Selected button as BlackOnWhite.
IF viewerToolData = NIL THEN RETURN;
viewerToolData.textSection.isSelected ← FALSE;
Labels.SetDisplayStyle[viewerToolData.textSection.selected, $BlackOnWhite, TRUE];
};
KillSelectionsButton:
PUBLIC
PROC [parent:
REF
ANY, clientData:
REF
ANY, mouseButton: MouseButton, shift, control:
BOOL] =
TRUSTED {
viewerToolData: ViewerToolData ← NARROW[clientData];
SVSelections.KillSkitterAndSelections[viewerToolData.editToolData];
};
DeleteJacksButton:
PUBLIC
PROC [parent:
REF
ANY, clientData:
REF
ANY, mouseButton: MouseButton, shift, control:
BOOL] =
TRUSTED {
viewerToolData: ViewerToolData ← NARROW[clientData];
scene: Scene ← viewerToolData.scene;
DisplayList3d.DeleteAllPrimitivesOfClass["jack", scene];
SVEditUser.PaintSceneAllViewers[SVViewerUser.EraseAndDrawSceneEtc, viewerToolData.editToolData, scene];
};
Input Notify Procs
SingleRay:
PUBLIC
PROC [viewerToolData: ViewerToolData, cameraPoint: Point2d] =
TRUSTED {
f: IO.STREAM ← SVError.GetErrorStream[];
color: Color;
xInt, yInt: INTEGER;
tree: CSGTree;
scene: Scene ← viewerToolData.scene;
camera: Camera ← viewerToolData.camera;
class: Classification;
rayWorld: Ray;
xInt ← Real.FixI[cameraPoint[1]]; yInt ← Real.FixI[cameraPoint[2]];
tree ← DisplayListToTree.AssemblyToTree[scene.assembly, scene, camera];
color ← CastRays.SingleRay[xInt, yInt, tree, scene.lightSources, camera, TRUE, f];
f.PutF["[%g,%g]: ",[real[cameraPoint[1]]], [real[cameraPoint[2]]]];
TFO3d.FileoutColor[f, color];
f.PutChar[IO.CR];
[class, rayWorld] ← CastRays.SingleRay2[[xInt, yInt], tree, camera, FALSE];
ClassToStream[f, class];
f.PutChar[IO.CR];
CastRays.SortClassByPrimitive[class];
ClassToStream[f, class];
f.PutChar[IO.CR];
CSG.ReturnRayToPool[rayWorld];
CastRays.ReturnClassToPool[class];
f.PutChar[IO.CR];
};
ClassToStream:
PROC [f:
IO.
STREAM, class: Classification] = {
FOR i:
NAT
IN [1..class.count]
DO
f.PutF["(%g, %g) ", IO.rope[class.primitives[i].name], IO.real[class.params[i]]];
ENDLOOP;
};
PointAt: PUBLIC PROC [viewerToolData: ViewerToolData, cameraPoint: Point2d] = TRUSTED {
Adds a new assembly to the scene of class "CoordSys", isTool is true. The first one will be pointer.0, the second pointer.1 and so on. Pointer will be defined with respect to the parent of the assembly which we are pointing at. If we are not pointing at anything, don't create a pointer. Just return.
f: IO.STREAM ← SVError.GetErrorStream[];
tree: CSGTree;
normal: Vector;
prim: Primitive;
scene: Scene ← viewerToolData.scene;
camera: Camera ← viewerToolData.camera;
class: Classification;
tree ← DisplayListToTree.AssemblyToTree[scene.assembly, scene, camera];
class ← CastRays.SingleRay2[cameraPoint, tree, camera, TRUE, TRUE, f];
IF class.count = 0 THEN RETURN;
prim ← class.primitives[1];
normal ← class.normals[1];
};
DrawSlice:
PUBLIC
PROC [viewerToolData: ViewerToolData, slice: Slice] = {
camera: Camera ← viewerToolData.camera;
DoDrawSlice:
PROC [dc: Graphics.Context] =
TRUSTED {
SVSlices.DrawSlice3d[dc, slice, camera];
};
SVViewerUser.Painter[DoDrawSlice, viewerToolData];
};
ComplementOldSelection: PUBLIC PROC [viewerToolData: ViewerToolData, selection: Selection, selectionType: SelectionType] = TRUSTED {
If selection is in this viewer then just complement it normally. If it is in another viewer, then have that viewer complement it. If it is a null selection, forget it.
IF selection = NIL THEN RETURN; -- null selection
IF selection.assembly = NIL THEN RETURN; -- null selection
IF selection.viewerToolData = viewerToolData
THEN ComplementSelection[viewerToolData, selection, selectionType]
ELSE ComplementSelection[selection.viewerToolData, selection, selectionType];
};
DrawSelectionOpaque: PROC [viewerToolData: ViewerToolData, selection: Selection, color: Color] = TRUSTED {
DoDrawSelectionOpaque: SAFE PROC [dc: Graphics.Context] = TRUSTED {
[] ← Graphics.SetPaintMode[dc, opaque];
Graphics.SetColor[dc, color];
SVViewerUser.DrawOneCS[dc, viewerToolData, selection.coordSys];
};
CoordSys.TellAboutParent[selection.coordSys];
SVViewerUser.Painter[DoDrawSelectionOpaque, viewerToolData];
};
ComplementSelection: PUBLIC PROC [viewerToolData: ViewerToolData, selection: Selection, selectionType: SelectionType] = TRUSTED {
DoComplementSelection: SAFE PROC [dc: Graphics.Context] = TRUSTED {
DrawSelection[dc, viewerToolData, selection, selectionType, GraphicsColor.black];
};
SVViewerUser.Painter[DoComplementSelection, viewerToolData];
};
DrawSelection:
PROC [dc: Graphics.Context, viewerToolData: ViewerToolData, selection: Selection, selectionType: SelectionType, color: Color] =
TRUSTED {
SVTransforms.TellAboutParent[selection.coordSys];
[] ← Graphics.SetPaintMode[dc, invert];
Graphics.SetColor[dc, color];
IF selectionType = movee THEN SVViewerUser.DrawOneCS[dc, viewerToolData, selection.coordSys]
ELSE SVViewerUser.DrawOneTargetCS[dc, viewerToolData, selection.coordSys];
};
RayCastProgress:
PUBLIC CastRays.NotifyOfProgressProc =
TRUSTED {
PROC [currentY, minX, minY, maxX, maxY: REAL, clientData: REF ANY];
Draw a box of width 10 and length currentY-minY+1 with origin at (minX, minY)
viewerToolData: ViewerToolData ← NARROW[clientData];
camera: Camera ← viewerToolData.camera;
width: REAL ← 10;
box: Graphics.Box;
lowLeft, upRight: Point2d;
DoRayCastProgress:
PROC [dc: Graphics.Context] =
TRUSTED {
Graphics.SetColor[dc, GraphicsColor.black];
Graphics.DrawBox[dc, box];
};
lowLeft ← CoordSys.CameraToScreen[[minX, minY], camera.screenCS];
upRight ← CoordSys.CameraToScreen[[maxX, currentY], camera.screenCS];
box ← [lowLeft[1], lowLeft[2], upRight[1], upRight[2]];
SVViewerUser.Painter[DoRayCastProgress, viewerToolData];
};
END.