File: SVViewerUserImplA.mesa
Author: Eric Bier in October 1982
Copyright © 1984 by Xerox Corporation. All rights reserved.
Last edited by Bier on January 15, 1985 0:12:23 am PST
Contents: Code to respond to button presses made in an SVViewer
DIRECTORY
BasicTime,
BitMap3d,
CastRays,
CGDevice,
Containers,
CoordSys,
DisplayList3d,
DisplayListToTree,
FileNames,
FS,
Graphics,
GraphicsBasic,
GraphicsColor,
IO,
Matrix3d,
Menus,
Preprocess3d,
Real,
Rope,
SV2d,
SV3d,
SVDraw3d,
SVDrawMonitor,
SVEditUser,
SVError,
SVFiles,
SVInterfaceTypes,
SVModelTypes,
SVRayTypes,
SVSceneTypes,
SVSelections,
SVTransforms,
SVViewerTool,
SVViewerUser,
TFI3d,
TFO3d,
ViewerClasses,
ViewerOps,
ViewerTools;
SVViewerUserImplA:
CEDAR
PROGRAM
IMPORTS BasicTime, BitMap3d, CastRays, CoordSys, DisplayList3d, DisplayListToTree, FileNames, FS, Graphics, IO, Matrix3d, Preprocess3d, Real, Rope, SVDraw3d, SVEditUser, SVError, SVFiles, SVSelections, SVTransforms, SVViewerUser, TFI3d, TFO3d, ViewerOps, ViewerTools
EXPORTS GraphicsBasic, SVViewerUser =
BEGIN
Assembly: TYPE = SVSceneTypes.Assembly;
BoundBox: TYPE = SVModelTypes.BoundBox;
Camera: TYPE = SVModelTypes.Camera;
Color: TYPE = GraphicsColor.Color;
CoordSysGenerator: TYPE = DisplayList3d.CoordSysGenerator;
CoordSystem: TYPE = SVModelTypes.CoordSystem;
CSGTree: TYPE = SVRayTypes.CSGTree;
DeviceObject: PUBLIC TYPE = CGDevice.Rep;
DrawStyle: TYPE = SVModelTypes.DrawStyle;
FileCamera: TYPE = SVSceneTypes.FileCamera;
EditToolData: TYPE = SVEditUser.EditToolData;
MasterObject: TYPE = SVSceneTypes.MasterObject;
Matrix4by4: TYPE = SV3d.Matrix4by4;
MouseButton: TYPE = Menus.MouseButton;
Point2d: TYPE = SV2d.Point2d;
Primitive: TYPE = SVRayTypes.Primitive;
Scene: TYPE = SVSceneTypes.Scene;
Vector: TYPE = SV3d.Vector;
Viewer: TYPE = ViewerClasses.Viewer;
ViewerToolData: TYPE = SVInterfaceTypes.ViewerToolData;
DCProc: TYPE = SVInterfaceTypes.DCProc;
TEXT VIEWER PARSING CODE (deserves its own module)
ReadTwoReals:
PUBLIC
PROC [textViewer: Viewer]
RETURNS [x, y:
REAL] =
TRUSTED {
wholeRope: Rope.ROPE ← ViewerTools.GetContents[textViewer];
wholeStream: IO.STREAM ← IO.RIS[wholeRope];
TFI3d.ReadBlank[wholeStream];
x ← TFI3d.ReadReal[wholeStream];
TFI3d.ReadBlankAndRope[wholeStream, ","];
y ← TFI3d.ReadReal[wholeStream];
};
MISCELLANEOUS
Painter:
PUBLIC
PROC [proc: DCProc, viewerToolData: ViewerToolData ←
NIL] =
TRUSTED {
scene: Scene ← viewerToolData.scene;
camera: Camera ← viewerToolData.camera;
viewerToolData.proc ← proc;
SVDrawMonitor.PrepareToDrawScene[];
ViewerOps.PaintViewer[viewer: viewerToolData.viewerPicture,
hint: client,
whatChanged: viewerToolData,
clearClient: FALSE];
SVDrawMonitor.DoneDrawingScene[];
}; -- end of Painter
UpdateHeader:
PUBLIC
PROC [pictureFile: Rope.
ROPE, viewerToolData: ViewerToolData] =
TRUSTED {
headerRope: Rope.ROPE;
aisName: Rope.ROPE;
viewName: Rope.ROPE ← viewerToolData.camera.viewName;
IF pictureFile = NIL THEN pictureFile ← viewerToolData.scene.name;
headerRope ← Rope.Cat[viewName, " View of Solid Scene: ", pictureFile];
aisName ← Rope.Concat[SVFiles.FilenameMinusExtension[pictureFile], ".ais"];
viewerToolData.outer.name ← headerRope;
ViewerOps.PaintViewer[viewerToolData.outer, caption, FALSE, NIL];
};
NewVersion:
PUBLIC
PROC [viewer: Viewer] =
TRUSTED {
viewerToolData: ViewerToolData ← NARROW[viewer.data];
scene: Scene ← viewerToolData.scene;
scene.dirty ← TRUE;
viewerToolData.treeOutOfDate ← TRUE;
viewerToolData.outer.newVersion ← TRUE;
UpdateHeader[scene.name, viewerToolData];
};
SceneOldVersion:
PUBLIC
PROC [viewerToolData: ViewerToolData] =
TRUSTED {
Tell EditTool that scene is no longer dirty. EditTool will call back all affected viewers using OldVersion (see below).
scene: Scene ← viewerToolData.scene;
SVEditUser.SceneOldVersion[viewerToolData, scene];
};
OldVersion:
PUBLIC
PROC [viewer: Viewer] =
TRUSTED {
viewerToolData: ViewerToolData ← NARROW[viewer.data];
scene: Scene ← viewerToolData.scene;
scene.dirty ← FALSE;
viewerToolData.treeOutOfDate ← TRUE; -- OldVersion may result from loading a new scene, or creating an empty scene. In either case, the ray tracing tree is out of date. Set flag just in case.
viewerToolData.outer.newVersion ← FALSE;
UpdateHeader[scene.name, viewerToolData];
};
DRAW SOMETHING IN A SOLID VIEWER (Fetches a display context first)
EraseAndDrawScene:
PUBLIC
PROC [viewerToolData: ViewerToolData] =
TRUSTED {
-- like DrawSceneButton but erases the screen before drawing.
DoDrawScene:
PROC [dc: Graphics.Context] =
TRUSTED {
EraseAndDrawSceneEtc[dc, viewerToolData];
};
Painter[DoDrawScene, viewerToolData];
};
DrawOneCSInViewer:
PUBLIC
PROC [viewerToolData: ViewerToolData, cs: CoordSystem] =
TRUSTED {
DoDrawOneCSInViewer:
PROC [dc: Graphics.Context] =
TRUSTED {
DrawOneCS[dc, viewerToolData, cs];
};
Painter[DoDrawOneCSInViewer, viewerToolData];
};
ComplementAssembly:
PUBLIC
PROC [viewerToolData: ViewerToolData, assem: Assembly] = {
DoComplementAssembly:
PROC [dc: Graphics.Context] =
TRUSTED {
SVViewerUser.DrawAssemblyXOR[dc, viewerToolData, assem];
};
SVViewerUser.Painter[DoComplementAssembly, viewerToolData];
};
DRAW A SET OF ITEMS INTO A GIVEN DISPLAY CONTEXT
DrawAssemblyXOR:
PUBLIC
PROC [dc: Graphics.Context, viewerToolData: ViewerToolData, assembly: Assembly] =
TRUSTED {
scene: Scene;
camera: Camera;
paintMode: Graphics.PaintMode;
scene ← viewerToolData.scene;
camera ← viewerToolData.camera;
paintMode ← Graphics.SetPaintMode[dc, invert];
BitMap3d.Erase[viewerToolData.xorDC];
DisplayList3d.DrawAssembly[dc, assembly, scene, camera];
SVSelections.ComplementAnySelectionsOnDC[viewerToolData.xorDC.dc, assembly, scene];
BitMap3d.DrawAltDisplayContext[dc, viewerToolData.xorDC];
[] ← Graphics.SetPaintMode[dc, paintMode];
};
DrawAssembly:
PUBLIC
PROC [dc: Graphics.Context, viewerToolData: ViewerToolData, assembly: Assembly] =
TRUSTED {
scene: Scene;
camera: Camera;
scene ← viewerToolData.scene;
camera ← viewerToolData.camera;
DisplayList3d.DrawAssembly[dc, assembly, scene, camera];
};
DrawSceneEtc:
PUBLIC
PROC [dc: Graphics.Context, viewerToolData: ViewerToolData, hardcopy:
BOOL ← FALSE] =
TRUSTED {
May also draw coordinate systems, drawing planes, etc depending on the current selected modes.
scene: Scene ← viewerToolData.scene;
camera: Camera ← viewerToolData.camera;
IF viewerToolData.doubleBuffer
AND
NOT hardcopy
THEN {
BitMap3d.Erase[viewerToolData.altDC];
DisplayList3d.DrawScene[viewerToolData.altDC.dc, scene, camera];
Make sure coordinate systems and selections will be drawn in black.
Graphics.SetColor[dc, GraphicsColor.black];
IF viewerToolData.showCoordSys
THEN
DrawAllCS[viewerToolData.altDC.dc, viewerToolData];
SVSelections.ComplementAnySelectionsDC[viewerToolData.altDC.dc, viewerToolData];
BitMap3d.DrawAltDisplayContext[dc, viewerToolData.altDC];
}
ELSE {
editToolData: EditToolData ← NARROW[viewerToolData.editToolData];
DisplayList3d.DrawScene[dc, scene, camera];
Make sure coordinate systems and selections will be drawn in black.
Graphics.SetColor[dc, GraphicsColor.black];
IF viewerToolData.showCoordSys
THEN
DrawAllCS[dc, viewerToolData];
SVSelections.ComplementAnySelectionsDC[dc, viewerToolData];
};
}; -- end of DrawSceneEtc
Put this code back into the ELSE clause to implement the display of coordinate frames only for the current STAR assembly.
IF viewerPictureData.showCoordSys THEN
IF editToolData.sceneSection.currentScene = scene THEN {
[assem, success] ← SVEditUser.TGetAssembly[editToolData.sceneSection.assemblyName, scene];
IF success THEN DrawOneCS[dc, viewerToolData, assem.coordSys];
};
EraseAndDrawSceneEtc:
PUBLIC
PROC [dc: Graphics.Context, viewerToolData: ViewerToolData] =
TRUSTED {
May also draw coordinate systems, drawing planes, etc depending on the current selected modes.
scene: Scene ← viewerToolData.scene;
camera: Camera ← viewerToolData.camera;
IF viewerToolData.doubleBuffer
THEN {
BitMap3d.Erase[viewerToolData.altDC];
DisplayList3d.DrawScene[viewerToolData.altDC.dc, scene, camera];
BitMap3d.DrawAltDisplayContext[dc, viewerToolData.altDC];
IF viewerToolData.showCoordSys
THEN
DrawAllCS[dc, viewerToolData];
SVSelections.ComplementAnySelectionsDC[dc, viewerToolData];
}
ELSE {
Graphics.SetColor[dc, GraphicsColor.white];
Graphics.DrawBox[dc, Graphics.GetBounds[dc]];
First we erase the old context white (this is a little wasteful since some of the DrawScene options draw in a background color -- however, some don't).
DisplayList3d.DrawScene[dc, scene, camera];
Graphics.SetColor[dc, GraphicsColor.black];
IF viewerToolData.showCoordSys
THEN
DrawAllCS[dc, viewerToolData];
SVSelections.ComplementAnySelectionsDC[dc, viewerToolData];
};
}; -- end of EraseAndDrawSceneEtc
DrawAllCS:
PUBLIC
PROC [dc: Graphics.Context, viewerToolData: ViewerToolData] =
TRUSTED {
scene: Scene ← viewerToolData.scene;
camera: Camera ← viewerToolData.camera;
g: CoordSysGenerator ← DisplayList3d.GetCoordSysGenerator[scene];
mat: Matrix4by4;
FOR cs: CoordSystem ← DisplayList3d.NextCoordSys[g], DisplayList3d.NextCoordSys[g]
UNTIL cs = NIL DO
mat ← CoordSys.FindInTermsOfCamera[cs, camera.coordSys];
Make sure you have up to date coordSys positions.
SVDraw3d.DrawCoordSys[dc, mat, camera];
ENDLOOP;
};
DrawOneCS:
PUBLIC
PROC [dc: Graphics.Context, viewerToolData: ViewerToolData, cs: CoordSystem] =
TRUSTED {
camera: Camera ← viewerToolData.camera;
Assume that cs has a valid cs.wrtCamera field.
SVDraw3d.DrawCoordSys[dc, cs.wrtCamera, camera];
};
MENU PROCS
PlaceOrigin:
PUBLIC
PROC [viewer: Viewer] =
TRUSTED {
viewer is the viewerPicture
Find the center of the solid window in solid window coordinates.
originX, originY: REAL;
transMat: Matrix4by4;
viewerToolData: ViewerToolData ← NARROW[viewer.data];
screenCS: CoordSystem;
camera: Camera ← viewerToolData.camera;
screenCS ← camera.screenCS;
originX ← viewer.cw;-- convert window width to real
originY ← viewer.ch;-- convert window height to real
originX ← originX/2.0;-- find the midpoint in window coords
originY ← originY/2.0;
transMat ← Matrix3d.MakeTranslateMat[-originX,-originY,0];
SVTransforms.AbsTransf[screenCS, camera.coordSys, transMat];
}; -- end of PlaceOrigin
ResizeBitMaps:
PUBLIC
PROC [viewer: Viewer] =
TRUSTED {
viewer is the viewerPicture
resize its bitMap
viewerToolData: ViewerToolData ← NARROW[viewer.data];
BitMap3d.ResizeBitMap[viewer, viewerToolData.altDC];
BitMap3d.ResizeBitMap[viewer, viewerToolData.xorDC];
};
DrawSceneButton:
PUBLIC
PROC [parent:
REF
ANY, clientData:
REF
ANY, mouseButton: MouseButton, shift, control:
BOOL] =
TRUSTED {
Menus.MenuProc
viewer is a SolidWindow. clientData is viewerToolData
viewerToolData: ViewerToolData ←
NARROW[clientData];
DoDrawScene: PROC [dc: Graphics.Context] = TRUSTED {
DrawSceneEtc[dc, viewerToolData];
};
Painter[DoDrawScene, viewerToolData];
};
Reset:
PUBLIC
PROC [parent:
REF
ANY, clientData:
REF
ANY, mouseButton: MouseButton, shift, control:
BOOL] =
TRUSTED {
viewerToolData: ViewerToolData ← NARROW[clientData];
editToolData: EditToolData ← viewerToolData.editToolData;
success: BOOL;
wdir: Rope.ROPE;
scene: Scene ← viewerToolData.scene;
wdir ← editToolData.originalWorkingDirectory;
[scene, success] ← SVEditUser.LoadScene[viewerToolData, scene.name, wdir];
Reload this scene from its backing file.
IF success
THEN {
viewerToolData.scene ← scene;
SVSelections.KillSkitterAndSelections[editToolData];
SceneOldVersion[viewerToolData];
UpdateHeader[scene.name, viewerToolData];
EraseAndDrawScene[viewerToolData];
SVViewerUser.Selected[parent, clientData, mouseButton, shift, control];
};
}; -- end of Reset
ConfirmReset:
PUBLIC
PROC [parent:
REF
ANY, clientData:
REF
ANY, mouseButton: MouseButton, shift, control:
BOOL] =
TRUSTED {
viewerToolData: ViewerToolData ← NARROW[clientData];
scene: Scene ← viewerToolData.scene;
rope: Rope.ROPE;
dirty: BOOL;
dirty ← viewerToolData.outer.newVersion;
IF dirty THEN rope ← "Confirm discard of edits"
ELSE rope ← IO.PutFR["Confirm reset of %g", [rope[scene.name]]];
SVError.AppendHerald[rope, TRUE];
}; -- end of ConfirmReset
Save:
PUBLIC
PROC [parent:
REF
ANY, clientData:
REF
ANY, mouseButton: MouseButton, shift, control:
BOOL] =
TRUSTED {
viewerToolData: ViewerToolData ← NARROW[clientData];
success: BOOL;
sceneName: Rope.ROPE;
scene: Scene ← viewerToolData.scene;
sceneName ← FileNames.StripVersionNumber[scene.name];
success ← SVEditUser.SaveScene[viewerToolData, sceneName];
IF success
THEN {
SVViewerUser.Selected[parent, clientData, mouseButton, shift, control];
SceneOldVersion[viewerToolData];
UpdateHeader[scene.name, viewerToolData];
};
}; -- end of Save
ConfirmSave:
PUBLIC
PROC [parent:
REF
ANY, clientData:
REF
ANY, mouseButton: MouseButton, shift, control:
BOOL] =
TRUSTED {
viewerToolData: ViewerToolData ← NARROW[clientData];
scene: Scene ← viewerToolData.scene;
exists: BOOL;
rope: Rope.ROPE;
exists ← SVFiles.FileExists[scene.name];
IF exists THEN rope ← IO.PutFR["Confirm Save to %g [Old File]", [rope[scene.name]]]
ELSE {
rope ← IO.PutFR["%g doesn't exist. Use Store", [rope[scene.name]]];
SVError.Blink[]
};
SVError.Append[rope, TRUE, TRUE];
};
Get:
PUBLIC
PROC [parent:
REF
ANY, clientData:
REF
ANY, mouseButton: MouseButton, shift, control:
BOOL] =
TRUSTED {
viewerToolData: ViewerToolData ← NARROW[clientData];
editToolData: EditToolData ← NARROW[viewerToolData.editToolData];
success: BOOL;
picName: Rope.ROPE ← ViewerTools.GetSelectionContents[];
fullName: Rope.ROPE;
aisName, wdir: Rope.ROPE;
scene: Scene;
oldScreenCS: CoordSystem ← viewerToolData.camera.screenCS;
TIMING VARIABLES
startTime: BasicTime.GMT;
endTime: BasicTime.GMT;
totalTime: INT;
timeRope: Rope.ROPE;
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;
START TIMING
startTime ← BasicTime.Now[];
[scene, success] ← SVEditUser.LoadScene[viewerToolData, fullName, wdir];
IF success
THEN {
fileCamera: FileCamera;
cameraName: Rope.ROPE;
END TIMING
endTime ← BasicTime.Now[];
totalTime ← BasicTime.Period[startTime, endTime];
timeRope ← IO.PutFR[" Done loading %g in time (%r)", [rope[fullName]], [integer[totalTime]]];
SVError.Append[timeRope, TRUE, TRUE];
IF scene.cameraOrder = NIL THEN fileCamera ← scene.cameras.first
ELSE {
cameraName ← scene.cameraOrder.first;
[fileCamera, success] ← DisplayList3d.FindFileCameraFromName[cameraName, scene];
IF
NOT success
THEN {
fileCamera ← scene.cameras.first;
SVError.Append[Rope.Cat["Camera ", cameraName, " not found"], TRUE, TRUE];
SVError.Blink[];
};
};
viewerToolData.scene ← scene;
SVSelections.KillSkitterAndSelections[editToolData];
viewerToolData.camera ← DisplayList3d.CreateCamera[scene.coordSysRoot, CoordSys.CopyCoordSysFromAnyTree[oldScreenCS, "SCREEN", NIL, NIL]];
DisplayList3d.StuffCameraFromFileCamera[viewerToolData.camera, fileCamera, viewerToolData.camera.style];
SceneOldVersion[viewerToolData];
UpdateHeader[fullName, viewerToolData];
aisName ← Rope.Concat[SVFiles.FilenameMinusExtension[fullName], ".ais"];
ViewerTools.SetContents[viewerToolData.textSection.ais, aisName];
EraseAndDrawScene[viewerToolData];
SVViewerUser.Selected[parent, clientData, mouseButton, shift, control];
};
}; -- end of Get
ConfirmGet:
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;
picName: Rope.ROPE ← ViewerTools.GetSelectionContents[];
fullName, wdir: Rope.ROPE;
rope: Rope.ROPE;
success: BOOL ← TRUE;
dirty: BOOL;
IF Rope.Length[picName] = 0
THEN {
SVError.Append["Please select a file name.", TRUE, TRUE];
SVError.Blink[];
RETURN;
};
wdir ← editToolData.originalWorkingDirectory;
[fullName,,] ←
FS.ExpandName[picName, wdir
!
FS.Error =>
IF error.group = user
THEN {
SVError.Append[Rope.Concat["Get: ", error.explanation], TRUE, TRUE];
success ← FALSE;
CONTINUE;
}
];
IF NOT success THEN RETURN;
dirty ← viewerToolData.outer.newVersion;
IF dirty THEN rope ← IO.PutFR["Confirm discard of edits and load of %g", [rope[fullName]]]
ELSE rope ← IO.PutFR["Confirm load of %g", [rope[fullName]]];
SVError.Append[rope, TRUE, TRUE];
}; -- end of ConfirmGet
Store:
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: BOOL;
aisName: Rope.ROPE;
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;
success ← SVEditUser.StoreScene[viewerToolData, scene, fullName];
IF success
THEN {
UpdateHeader[fullName, viewerToolData];
SVViewerUser.Selected[parent, clientData, mouseButton, shift, control];
SceneOldVersion[viewerToolData];
UpdateHeader[scene.name, viewerToolData];
aisName ← Rope.Concat[SVFiles.FilenameMinusExtension[fullName], ".ais"];
ViewerTools.SetContents[viewerToolData.textSection.ais, aisName];};
}; -- end of Store
ConfirmStore:
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;
picName: Rope.ROPE ← ViewerTools.GetSelectionContents[];
fullName, wdir: Rope.ROPE;
exists: BOOL;
success: BOOL ← TRUE;
rope: Rope.ROPE;
IF Rope.Length[picName] = 0
THEN {
SVError.Append["Please select a file name.", TRUE, TRUE];
SVError.Blink[];
RETURN;
};
wdir ← editToolData.originalWorkingDirectory;
[fullName,,] ←
FS.ExpandName[picName, wdir
!
FS.Error =>
IF error.group = user
THEN {
SVError.Append[Rope.Concat["Store: ", error.explanation], TRUE, TRUE];
success ← FALSE;
CONTINUE;
}
];
exists ← SVFiles.FileExists[fullName];
IF exists THEN rope ← IO.PutFR["Confirm Store of %g [Old File]", [rope[fullName]]]
ELSE rope ← IO.PutFR["Confirm Store to %g [New File]", [rope[fullName]]];
SVError.AppendHerald[rope, TRUE];
};
Split:
PUBLIC
PROC [parent:
REF
ANY, clientData:
REF
ANY, mouseButton: MouseButton, shift, control:
BOOL] =
TRUSTED {
Create a new viewer onto this scene. Update the ring of links joining all viewers onto this scene,
viewerToolData: ViewerToolData ← NARROW[clientData];
scene: Scene ← viewerToolData.scene;
SVEditUser.Split[viewerToolData, scene];
};
Erase:
PUBLIC
PROC [parent:
REF
ANY, clientData:
REF
ANY, mouseButton: MouseButton, shift, control:
BOOL] =
TRUSTED {
viewerToolData: ViewerToolData ← NARROW[clientData];
DoErase:
PROC [dc: Graphics.Context] =
TRUSTED {
mark: Graphics.Mark ← Graphics.Save[dc];
Graphics.SetColor[dc, Graphics.white];
Graphics.DrawBox[dc,Graphics.GetBounds[dc]];
Graphics.SetColor[dc, Graphics.white];
Graphics.Restore[dc,mark];
};
Painter[DoErase, viewerToolData];
};
Empty:
PUBLIC
PROC [parent:
REF
ANY, clientData:
REF
ANY, mouseButton: MouseButton, shift, control:
BOOL] =
TRUSTED {
Creates a new empty scene for the viewer to view.
viewerToolData: ViewerToolData ← NARROW[clientData];
editToolData: EditToolData ← viewerToolData.editToolData;
oldScene: Scene ← viewerToolData.scene;
newScene: Scene;
oldScreenCS: CoordSystem;
fileCamera: FileCamera;
cameraName: Rope.ROPE;
oldScreenCS ← viewerToolData.camera.screenCS;
newScene ← viewerToolData.scene ← DisplayList3d.CreateScene["NoName.pic"];
SVSelections.KillSkitterAndSelections[editToolData];
UpdateHeader[newScene.name, viewerToolData];
SVViewerUser.Selected[parent, clientData, mouseButton, shift, control];
IF newScene.cameraOrder = NIL THEN fileCamera ← newScene.cameras.first
ELSE {
success: BOOL;
cameraName ← newScene.cameraOrder.first;
[fileCamera, success] ← DisplayList3d.FindFileCameraFromName[cameraName, newScene];
IF
NOT success
THEN {
fileCamera ← newScene.cameras.first;
SVError.Append[Rope.Cat["Camera ", cameraName, " not found"], TRUE, TRUE];
SVError.Blink[];
};
};
viewerToolData.camera ← DisplayList3d.CreateCamera[newScene.coordSysRoot, CoordSys.CopyCoordSysFromAnyTree[oldScreenCS, "SCREEN", NIL, NIL]];
DisplayList3d.StuffCameraFromFileCamera[viewerToolData.camera, fileCamera, viewerToolData.camera.style];
Erase[parent, clientData, mouseButton, shift, control];
SVEditUser.NotifyOfEmpty[viewerToolData: viewerToolData, from: oldScene, to: viewerToolData.scene];
SceneOldVersion[viewerToolData];
This must be done after NotifyOfEmpty since SVEditUser expects to register to the newly created NoName scene before it resets the [New Version] headers.
ViewerTools.SetContents[viewerToolData.textSection.ais, "default.ais"];
};
ConfirmEmpty:
PUBLIC
PROC [parent:
REF
ANY, clientData:
REF
ANY, mouseButton: MouseButton, shift, control:
BOOL] =
TRUSTED {
viewerToolData: ViewerToolData ← NARROW[clientData];
scene: Scene ← viewerToolData.scene;
rope: Rope.ROPE;
dirty: BOOL;
dirty ← viewerToolData.outer.newVersion;
IF dirty THEN rope ← "Confirm discard of edits"
ELSE rope ← "Confirm emptying of viewer";
SVError.AppendHerald[rope, TRUE];
};
RayCast:
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;
tree: CSGTree;
startTime: BasicTime.GMT;
afterTreeTime: BasicTime.GMT;
endTime: BasicTime.GMT;
totalTime: INT;
outStream: IO.STREAM ← SVError.GetErrorStream[];
timeRope, wdir: Rope.ROPE;
aisFileRope: Rope.ROPE ← ViewerTools.GetContents[viewerToolData.textSection.ais];
success: BOOL;
wdir ← editToolData.originalWorkingDirectory;
success ← TRUE;
[aisFileRope,,] ←
FS.ExpandName[aisFileRope, wdir
!
FS.Error =>
IF error.group = user
THEN {
SVError.Append[Rope.Concat["RayCast: ", error.explanation], TRUE, TRUE];
success ← FALSE;
CONTINUE;
}
];
IF NOT success THEN RETURN;
startTime ← BasicTime.Now[];
tree ← DisplayListToTree.AssemblyToTree[scene.assembly, scene, camera];
afterTreeTime ← BasicTime.Now[];
totalTime ← BasicTime.Period[from: startTime, to: afterTreeTime];
timeRope ← IO.PutFR["Building tree took (%r)",[integer[totalTime]]];
SVError.Append[timeRope, TRUE, TRUE];
IF mouseButton = red
OR mouseButton = blue
THEN {
success ← CastRays.DrawTree[tree, scene.lightSources, camera, aisFileRope, mouseButton = blue, SVViewerUser.RayCastProgress, viewerToolData, outStream];
}
ELSE {
-- yellow bug
cameraPoint: Point2d;
[cameraPoint, ----] ← SVSelections.GetPositionSkitter[];
success ← CastRays.DrawTreeWithStartLine[cameraPoint[2], tree, scene.lightSources, camera, aisFileRope, mouseButton = blue, SVViewerUser.RayCastProgress, viewerToolData, outStream];
};
IF
NOT success
THEN {
outStream.PutF["...Raycast aborted."];
RETURN;
};
endTime ← BasicTime.Now[];
totalTime ← BasicTime.Period[from: afterTreeTime, to: endTime];
timeRope ← IO.PutFR[" Raycast took (%r)",[integer[totalTime]]];
SVError.Append[timeRope, TRUE, TRUE];
SVViewerUser.DrawBlackAndWhite[parent, clientData, mouseButton, shift, control];
}; -- end of RayCast
ConfirmRayCast:
PUBLIC
PROC [parent:
REF
ANY, clientData:
REF
ANY, mouseButton: MouseButton, shift, control:
BOOL] =
TRUSTED {
viewerToolData: ViewerToolData ← NARROW[clientData];
exists: BOOL;
aisFileRope: Rope.ROPE ← ViewerTools.GetContents[viewerToolData.textSection.ais];
redRope: Rope.ROPE ← Rope.Concat[SVFiles.FilenameMinusExtension[aisFileRope], "-red.ais"];
greenRope: Rope.ROPE ← Rope.Concat[SVFiles.FilenameMinusExtension[aisFileRope], "-green.ais"];
blueRope: Rope.ROPE ← Rope.Concat[SVFiles.FilenameMinusExtension[aisFileRope], "-blue.ais"];
rope: Rope.ROPE;
IF mouseButton = blue
THEN {
-- black and white only
exists ← SVFiles.FileExists[aisFileRope];
rope ← IO.PutFR["Confirm raycast to %g.", [rope[aisFileRope]]];
IF exists THEN rope ← Rope.Concat[rope, " [Old File]"]
ELSE rope ← Rope.Concat[rope, " [New File]"];
}
ELSE {
exists ← SVFiles.FileExists[aisFileRope] OR SVFiles.FileExists[redRope] OR SVFiles.FileExists[greenRope] OR SVFiles.FileExists[blueRope];
rope ← IO.PutFR["Confirm raycast to %g [-red, -green, -blue, plain].ais", [rope[SVFiles.FilenameMinusExtension[aisFileRope]]]];
IF exists THEN rope ← Rope.Concat[rope, " [Old Files]"]
ELSE rope ← Rope.Concat[rope, " [New Files]"];
};
SVError.AppendHerald[rope, TRUE];
};
Stop:
PUBLIC
PROC [parent:
REF
ANY, clientData:
REF
ANY, mouseButton: MouseButton, shift, control:
BOOL] =
TRUSTED {
viewerToolData: ViewerToolData ← NARROW[clientData];
camera: Camera ← viewerToolData.camera;
camera.abort ← TRUE;
};
ARay:
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;
Get x and y from appropriate slots. Interpret this as camera coordinates and draw a cross.
x, y: REAL;
xInt, yInt: INTEGER;
outHandle: IO.STREAM;
tree: CSGTree ← DisplayListToTree.AssemblyToTree[scene.assembly, scene, camera];
color: Color;
[x, y] ← ReadTwoReals[viewerToolData.textSection.xyz];
xInt ← Real.FixI[x]; yInt ← Real.FixI[y];
outHandle ← SVError.GetErrorStream[];
color ← CastRays.SingleRay[xInt, yInt,
tree, scene.lightSources, camera, TRUE, outHandle];
outHandle.PutF["[%g,%g]: ",[real[x]], [real[y]]];
TFO3d.FileoutColor[outHandle, color];
}; -- end of ARay
DrawCoordSystems:
PUBLIC
PROC [parent:
REF
ANY, clientData:
REF
ANY, mouseButton: MouseButton, shift, control:
BOOL] =
TRUSTED {
viewerToolData: ViewerToolData ← NARROW[clientData];
DoDrawCoordSys:
PROC [dc: Graphics.Context] =
TRUSTED {
DrawAllCS[dc, viewerToolData];
};
Painter[DoDrawCoordSys, viewerToolData];
};
DrawBoundBoxes:
PUBLIC
PROC [parent:
REF
ANY, clientData:
REF
ANY, mouseButton: MouseButton, shift, control:
BOOL] =
TRUSTED {
viewer is Container
viewerToolData: ViewerToolData ← NARROW[clientData];
scene: Scene ← viewerToolData.scene;
camera: Camera ← viewerToolData.camera;
tree: CSGTree;
DoDrawBoundBoxes:
PROC [dc: Graphics.Context] =
TRUSTED {
SVDraw3d.DrawBoundBoxes[dc, tree, camera];
};
tree ← DisplayListToTree.AssemblyToTree[scene.assembly, scene, camera]; -- does a TellAboutCameraAndWorld
[] ← Preprocess3d.PreprocessForInteraction[tree, camera];
Painter[DoDrawBoundBoxes, viewerToolData];
}; -- end of DrawBoundBoxes
DrawBoundSpheres:
PUBLIC
PROC [parent:
REF
ANY, clientData:
REF
ANY, mouseButton: MouseButton, shift, control:
BOOL] =
TRUSTED {
viewer is Container
viewerToolData: ViewerToolData ← NARROW[clientData];
scene: Scene ← viewerToolData.scene;
camera: Camera ← viewerToolData.camera;
tree: CSGTree;
DoDrawBoundSpheres:
PROC [dc: Graphics.Context] =
TRUSTED {
SVDraw3d.DrawBoundSpheres[dc, tree, camera];
};
tree ← DisplayListToTree.AssemblyToTree[scene.assembly, scene, camera]; -- does a TellAboutCameraAndWorld
[] ← Preprocess3d.PreprocessForSlice[tree, camera]; -- computes the bounding spheres
Painter[DoDrawBoundSpheres, viewerToolData];
}; -- end of DrawBoundSpheres
END.