File: SVViewerImpl.mesa
Author: Eric Bier on July 2, 1983 5:03 pm
Copyright © 1984 by Xerox Corporation. All rights reserved.
Last edited by Bier on January 18, 1985 3:58:27 pm PST
Contents: Code to create a solid viewer. Calls SVViewerTool to make the container and adds menus at the top. The 3D part of the solid viewer is a new viewer of class $SolidWindow. The paint proc for a $SolidWindow is defined herein.
DIRECTORY
BitMap3d,
Buttons,
Containers,
CoordSys,
DisplayList3d,
FS,
Graphics,
GraphicsColor,
Icons,
Labels,
Menus,
Rope,
SV2d,
SV3d,
SVDrawMonitor,
SVError,
SVInterfaceTypes,
SVModelTypes,
SVSceneTypes,
SVViewer,
SVViewerInput,
SVViewerTool,
SVViewerUser,
TIPUser,
VFonts,
ViewerClasses,
ViewerOps,
ViewerTools;
SVViewerImpl: PROGRAM
IMPORTS BitMap3d, Buttons, Containers, CoordSys, DisplayList3d, FS, Icons, Labels, Menus, Rope, SVError, SVViewerInput, SVViewerUser, SVViewerTool, TIPUser, VFonts, ViewerOps, ViewerTools
EXPORTS SVViewer
SHARES ViewerClasses =
BEGIN
Camera: TYPE = SVModelTypes.Camera;
CoordSystem: TYPE = SVModelTypes.CoordSystem;
EditToolData: TYPE = SVInterfaceTypes.EditToolData;
FileCamera: TYPE = SVSceneTypes.FileCamera;
MouseButton: TYPE = Menus.MouseButton;
Plane: TYPE = SV3d.Plane;
Point2d: TYPE = SV2d.Point2d;
Scene: TYPE = SVSceneTypes.Scene;
Viewer: TYPE = ViewerClasses.Viewer;
ViewerToolData: TYPE = REF ViewerToolDataObj;
ViewerToolDataObj: TYPE = SVInterfaceTypes.ViewerToolDataObj;
entryHeight: CARDINAL = 15; -- height of a line of items
entryVSpace: CARDINAL = 2; -- vertical leading between lines
entryHSpace: CARDINAL = 2; -- horizontal space between items on a line
column1: CARDINAL = 200; -- horizontal space between margin and column 1;
column2: CARDINAL = 250; -- horizontal space between margin and column 2.
column3: CARDINAL = 500; -- horizontal space between margin and column 3;
SolidPaint: SAFE PROC [self: Viewer, context: Graphics.Context, whatChanged: REF ANY, clear: BOOL] = TRUSTED {
ViewerClasses.PaintProc
whatChanged is a ViewerToolData. self is a ViewerPicture.
viewerToolData: ViewerToolData;
IF whatChanged = NIL THEN { --we are being called by Window Manager
viewerToolData ← NARROW[self.data];
SVViewerUser.PlaceOrigin[self];
SVViewerUser.ResizeBitMaps[self];
SVDrawMonitor.PrepareToDrawScene[];
SVViewerUser.EraseAndDrawSceneEtc[context, viewerToolData];
SVDrawMonitor.DoneDrawingScene[];
}
ELSE {
proc: PROC [Graphics.Context];
viewerToolData ← NARROW[whatChanged];
proc ← viewerToolData.proc;
proc[context];
RETURN};
};
Init: PROC = {
solidWindowClass: ViewerClasses.ViewerClass;
solidWindowClass ←
NEW[ViewerClasses.ViewerClassRec ← [
paint: SolidPaint,
notify: SVViewerInput.InputNotify,
tipTable: TIPUser.InstantiateNewTIPTable["SolidViews.TIP"]
]];
ViewerOps.RegisterViewerClass[$SolidWindow, solidWindowClass];
};
confirmReset: REF Menus.ClickProc ← NEW[Menus.ClickProc ← SVViewerUser.ConfirmReset];
confirmSave: REF Menus.ClickProc ← NEW[Menus.ClickProc ← SVViewerUser.ConfirmSave];
confirmGet: REF Menus.ClickProc ← NEW[Menus.ClickProc ← SVViewerUser.ConfirmGet];
confirmStore: REF Menus.ClickProc ← NEW[Menus.ClickProc ← SVViewerUser.ConfirmStore];
confirmEmpty: REF Menus.ClickProc ← NEW[Menus.ClickProc ← SVViewerUser.ConfirmEmpty];
confirmRayCast: REF Menus.ClickProc ← NEW[Menus.ClickProc ← SVViewerUser.ConfirmRayCast];
CreateViewerTool: PUBLIC PROC [parentData: REF ANY, scene: Scene, iconic: BOOL, paint: BOOL, workingDirectory: Rope.ROPE] RETURNS [viewerToolData: ViewerToolData, viewerPicture: Viewer] = {
parent is the EditTool
Create the Container and the top menu which looks like this:
Clear, Reset, Get, Store, Save, Split, Erase, Raycast, Stop, Aray, Press, Dither, Extend, Move
#BBox #Scene #Coords #Point #Cross #Color #B&W #Dither Coords
screenCS, worldCS: CoordSystem;
success: BOOL;
fileCamera: FileCamera;
vToolMenu: Menus.Menu ← Menus.CreateMenu[1];
editToolData: EditToolData;
iconFileName: Rope.ROPE;
viewerToolData ← NEW[ViewerToolDataObj];
Clear, Reset, Get, Store, Save, Split, Erase, Raycast, Stop, Aray, Press, Dither, StorePoly
Menus.AppendMenuEntry[
menu: vToolMenu,
entry: Menus.CreateEntry[
name: "Clear",
proc: SVViewerUser.Empty,
clientData: viewerToolData,
documentation: confirmEmpty,
guarded: TRUE
],
line: 0
];
Menus.AppendMenuEntry[
menu: vToolMenu,
entry: Menus.CreateEntry[
name: "Reset",
proc: SVViewerUser.Reset,
clientData: viewerToolData,
documentation: confirmReset,
guarded: TRUE
],
line: 0
];
Menus.AppendMenuEntry[
menu: vToolMenu,
entry: Menus.CreateEntry[
name: "Get",
proc: SVViewerUser.Get,
clientData: viewerToolData,
documentation: confirmGet,
guarded: TRUE
],
line: 0
];
Menus.AppendMenuEntry[
menu: vToolMenu,
entry: Menus.CreateEntry[
name: "Store",
proc: SVViewerUser.Store,
clientData: viewerToolData,
documentation: confirmStore,
guarded: TRUE
],
line: 0
];
Menus.AppendMenuEntry[
menu: vToolMenu,
entry: Menus.CreateEntry[
name: "Save",
proc: SVViewerUser.Save,
clientData: viewerToolData,
documentation: "Save the current picture file edits.",
guarded: FALSE
],
line: 0
];
Menus.AppendMenuEntry[
menu: vToolMenu,
entry: Menus.CreateEntry[
name: "Split",
proc: SVViewerUser.Split,
clientData: viewerToolData,
documentation: "Make another viewer onto this scene"
],
line: 0
];
Menus.AppendMenuEntry[
menu: vToolMenu,
entry: Menus.CreateEntry[
name: "Erase",
proc: SVViewerUser.Erase,
clientData: viewerToolData,
documentation: "Erase this window"
],
line: 0
];
Menus.AppendMenuEntry[
menu: vToolMenu,
entry: Menus.CreateEntry[
name: "RayCast",
proc: SVViewerUser.RayCast,
clientData: viewerToolData,
documentation: confirmRayCast,
guarded: TRUE
],
line: 0
];
Menus.AppendMenuEntry[
menu: vToolMenu,
entry: Menus.CreateEntry[
name: "Stop",
proc: SVViewerUser.Stop,
clientData: viewerToolData,
documentation: "stop ray casting",
guarded: FALSE
],
line: 0
];
Menus.AppendMenuEntry[
menu: vToolMenu,
entry: Menus.CreateEntry[
name: "ARay",
proc: SVViewerUser.ARay,
clientData: viewerToolData,
documentation: "Cast a ray from screen point given in this viewer's x, y, z blank"
],
line: 0
];
Menus.AppendMenuEntry[
menu: vToolMenu,
entry: Menus.CreateEntry[
name: "Press",
proc: SVViewerUser.Press,
clientData: viewerToolData,
documentation: "Do a DrawScene to the press file named in 'AIS:'"
],
line: 0
];
Menus.AppendMenuEntry[
menu: vToolMenu,
entry: Menus.CreateEntry[
name: "Dither",
proc: SVViewerUser.Dither,
clientData: viewerToolData,
documentation: "Create an 8 bit dithered image from 3 separations"
],
line: 0
];
Menus.AppendMenuEntry[
menu: vToolMenu,
entry: Menus.CreateEntry[
name: "StorePoly",
proc: SVViewerUser.StorePoly,
clientData: viewerToolData,
documentation: "Store scene in vertex-face type format"
],
line: 0
];
viewerToolData.editToolData ← NARROW[parentData];
viewerToolData.scene ← scene;
editToolData ← NARROW[parentData];
iconFileName ← Rope.Concat[editToolData.originalWorkingDirectory, "SolidViews.icons"];
Construct the outer container.
viewerToolData.outer ← SVViewerTool.Create[
info: [
name: Rope.Concat["Solid Scene: ", viewerToolData.scene.name],
menu: vToolMenu,
data: viewerToolData,
iconic: TRUE,
column: left,
scrollable: FALSE,
icon: Icons.NewIconFromFile[iconFileName, 0]
],
paint: FALSE];
Find the current scene.
screenCS ← CoordSys.CreateRoot["SCREEN"];
IF scene.cameraOrder # NIL THEN [fileCamera, ----] ← DisplayList3d.FindFileCameraFromName[scene.cameraOrder.first,
viewerToolData.scene]
ELSE {
[fileCamera, success] ← DisplayList3d.FindFileCameraFromName["Front",
viewerToolData.scene];
IF NOT success THEN ERROR;
};
worldCS ← scene.coordSysRoot;
viewerToolData.camera ← DisplayList3d.CreateCamera[worldCS, screenCS];
DisplayList3d.StuffCameraFromFileCamera[viewerToolData.camera, fileCamera, wire]; -- wireframe
viewerToolData.sceneStyleIndex ← 1; -- wireframe
viewerToolData.mode ← cast;
viewerToolData.showCoordSys ← FALSE;
viewerToolData.doubleBuffer ← FALSE;
viewerToolData.altDC ← BitMap3d.GetAltDisplayContext[];
viewerToolData.xorDC ← BitMap3d.GetAltDisplayContext[];
BuildLine1[viewerToolData];
BuildLine2[viewerToolData, workingDirectory];
BuildPictureSection[viewerToolData];
viewerPicture ← viewerToolData.viewerPicture;
IF paint THEN ViewerOps.ComputeColumn[viewerToolData.outer.column, TRUE];
IF NOT iconic THEN ViewerOps.OpenIcon[icon: viewerToolData.outer, closeOthers: FALSE, bottom: FALSE, paint: TRUE];
};
BuildLine1: PRIVATE PROC [viewerToolData: ViewerToolData] = {
This section implements a set of buttons, text windows, and options listers in this format:
Draw: BBox BSphere Scene Coords Point Cross Color B&W Dither CoordsMode
drawLabel, boxButton, sphereButton, sceneButton, drawCoordsButton, pointButton, crossButton, colorButton, bwButton, ditherButton, coordsButton: Buttons.Button;
viewerToolData.height ← viewerToolData.height + entryVSpace;
Space down from the top of the viewer.
drawLabel ← Labels.Create[
info: [
name: "Draw: ",
wy: viewerToolData.height,
wh: entryHeight,
parent: viewerToolData.outer, border: FALSE]
];
boxButton ← Buttons.Create[
info: [
name: "BBox",
wx: drawLabel.wx + drawLabel.ww + entryHSpace,
wy: viewerToolData.height, wh: entryHeight,
parent: viewerToolData.outer, border: FALSE],
proc: SVViewerUser.DrawBoundBoxes,
clientData: viewerToolData
];
sphereButton ← Buttons.Create[
info: [
name: "Sphere",
wx: boxButton.wx + boxButton.ww + entryHSpace,
wy: viewerToolData.height, wh: entryHeight,
parent: viewerToolData.outer, border: FALSE],
proc: SVViewerUser.DrawBoundSpheres,
clientData: viewerToolData
];
sceneButton ← Buttons.Create[
info: [
name: "Scene",
wx: sphereButton.wx + sphereButton.ww + entryHSpace,
wy: viewerToolData.height, wh: entryHeight,
parent: viewerToolData.outer, border: FALSE],
proc: SVViewerUser.DrawSceneButton,
clientData: viewerToolData
];
drawCoordsButton ← Buttons.Create[
info: [
name: "Coords",
wx: sceneButton.wx + sceneButton.ww + entryHSpace,
wy: viewerToolData.height, wh: entryHeight,
parent: viewerToolData.outer, border: FALSE],
proc: SVViewerUser.DrawCoordSystems,
clientData: viewerToolData
];
pointButton ← Buttons.Create[
info: [
name: "Point", wx: drawCoordsButton.wx + drawCoordsButton.ww + entryHSpace, wy: viewerToolData.height, wh: entryHeight, parent: viewerToolData.outer, border: FALSE],
proc: SVViewerUser.DrawPt,
clientData: viewerToolData
];
crossButton ← Buttons.Create[
info: [name: "Cross",
wx: pointButton.wx + pointButton.ww + entryHSpace,
wy: viewerToolData.height, wh: entryHeight,
parent: viewerToolData.outer, border: FALSE],
proc: SVViewerUser.CrossHairs,
clientData: viewerToolData
];
colorButton ← Buttons.Create[
info: [
name: "Color",
wx: crossButton.wx + crossButton.ww + entryHSpace,
wy: viewerToolData.height, wh: entryHeight,
parent: viewerToolData.outer, border: FALSE],
proc: SVViewerUser.DrawColor,
clientData: viewerToolData
];
bwButton ← Buttons.Create[
info: [
name: "B&W",
wx: colorButton.wx + colorButton.ww + entryHSpace,
wy: viewerToolData.height, wh: entryHeight,
parent: viewerToolData.outer, border: FALSE],
proc: SVViewerUser.DrawBlackAndWhite,
clientData: viewerToolData
];
ditherButton ← Buttons.Create[
info: [
name: "Dither",
wx: bwButton.wx + bwButton.ww + entryHSpace,
wy: viewerToolData.height, wh: entryHeight,
parent: viewerToolData.outer, border: FALSE],
proc: SVViewerUser.DrawDither,
clientData: viewerToolData
];
coordsButton ← Buttons.Create[
info: [
name: "CoordsMode",
wx: ditherButton.wx + ditherButton.ww + entryHSpace,
wy: viewerToolData.height, wh: entryHeight,
parent: viewerToolData.outer, border: FALSE],
proc: SVViewerUser.ShowCoordsMode,
clientData: viewerToolData
];
viewerToolData.height ← viewerToolData.height + entryVSpace + entryHeight;
}; -- end of BuildLine1
BuildLine2: PRIVATE PROC [viewerToolData: ViewerToolData, workingDirectory: Rope.ROPE] = {
This section implements a set of buttons, text windows, and options listers in this format:
Text: <somefile> Style: <drawStyle> x,y,z: <x, y, z> Selected 2Buffer
AIS: <filename> Kill Selections DeleteJacks
textPrompt, aisPrompt, stylePrompt: Buttons.Button;
xyzPrompt, doubleBufferButton: Buttons.Button;
killSelectionsButton, deleteJacksButton: Buttons.Button;
textPrompt ← Buttons.Create[
info: [
name: "Text:", wy: viewerToolData.height, wh: entryHeight,
parent: viewerToolData.outer, border: FALSE],
proc: SVViewerUser.TextPrompt,
clientData: viewerToolData
];
viewerToolData.textSection.text ← ViewerTools.MakeNewTextViewer[[
parent: viewerToolData.outer,
wx: textPrompt.wx + textPrompt.ww + entryHSpace,
wy: viewerToolData.height,
ww: VFonts.StringWidth["///Users/Name.pa/Solidviews/PictureName.pic"],
wh: entryHeight,
data: "NoName.pic",
scrollable: FALSE, border: FALSE]];
stylePrompt ← Buttons.Create[
info: [
name: "Style:",
wx: viewerToolData.textSection.text.wx +
viewerToolData.textSection.text.ww + entryHSpace,
wy: viewerToolData.height, wh: entryHeight,
parent: viewerToolData.outer, border: FALSE],
proc: SVViewerUser.StylePrompt,
clientData: viewerToolData
];
viewerToolData.textSection.viewStyle ← Labels.Create[
info: [
name: "WireFrame",
wx: stylePrompt.wx + stylePrompt.ww + entryHSpace,
wy: viewerToolData.height, wh: entryHeight,
ww: VFonts.StringWidth["ALongStyle"],
parent: viewerToolData.outer, border: FALSE]];
X, Y, Z:<x, y, z>DoubleBuffer Selected
xyzPrompt ← Buttons.Create[
info: [
name: "x,y,z:",
wx: viewerToolData.textSection.viewStyle.wx +
viewerToolData.textSection.viewStyle.ww + entryHSpace,
wy: viewerToolData.height, wh: entryHeight,
parent: viewerToolData.outer, border: FALSE],
proc: SVViewerUser.XYZPrompt,
clientData: viewerToolData
];
viewerToolData.textSection.xyz ← ViewerTools.MakeNewTextViewer[[
parent: viewerToolData.outer,
wx: xyzPrompt.wx + xyzPrompt.ww + entryHSpace,
wy: viewerToolData.height,
ww: VFonts.StringWidth["18, 18, 18"],
wh: entryHeight,
data: "0, 0, 0",
scrollable: FALSE, border: FALSE]];
viewerToolData.textSection.selected ← Buttons.Create[
info: [
name: "Selected",
wx: viewerToolData.textSection.xyz.wx +
viewerToolData.textSection.xyz.ww + entryHSpace,
wy: viewerToolData.height, wh: entryHeight,
parent: viewerToolData.outer, border: FALSE],
proc: SVViewerUser.Selected,
clientData: viewerToolData
];
doubleBufferButton ← Buttons.Create[
info: [
name: "2Buffer",
wx: viewerToolData.textSection.selected.wx +
viewerToolData.textSection.selected.ww + entryHSpace,
wy: viewerToolData.height, wh: entryHeight,
parent: viewerToolData.outer, border: FALSE],
proc: SVViewerUser.DoubleBuffer,
clientData: viewerToolData
];
viewerToolData.height ← viewerToolData.height + entryVSpace + entryHeight;
aisPrompt ← Buttons.Create[
info: [
name: "AIS:",
wy: viewerToolData.height, wh: entryHeight,
parent: viewerToolData.outer, border: FALSE],
proc: SVViewerUser.AISPrompt,
clientData: viewerToolData
];
viewerToolData.textSection.ais ← ViewerTools.MakeNewTextViewer[[
parent: viewerToolData.outer,
wx: aisPrompt.wx + aisPrompt.ww + entryHSpace,
wy: viewerToolData.height,
ww: VFonts.StringWidth["///Users/SomeName.pa/Solidviews/PictureName.ais"],
wh: entryHeight,
data: Rope.Concat[workingDirectory, "NoName.ais"],
scrollable: FALSE, border: FALSE]];
killSelectionsButton ← Buttons.Create[
info: [
name: "KillSelections",
wx: viewerToolData.textSection.ais.wx +
viewerToolData.textSection.ais.ww + entryHSpace,
wy: viewerToolData.height, wh: entryHeight,
parent: viewerToolData.outer, border: FALSE],
proc: SVViewerUser.KillSelectionsButton,
clientData: viewerToolData
];
deleteJacksButton ← Buttons.Create[
info: [
name: "DeleteJacks",
wx: killSelectionsButton.wx +
killSelectionsButton.ww + entryHSpace,
wy: viewerToolData.height, wh: entryHeight,
parent: viewerToolData.outer, border: FALSE],
proc: SVViewerUser.DeleteJacksButton,
clientData: viewerToolData
];
viewerToolData.height ← viewerToolData.height + entryVSpace + entryHeight;
}; -- end of BuildTextSection
BuildPictureSection: PRIVATE PROC [viewerToolData: ViewerToolData] = {
Create a SolidWindow which fills the bottom of the container
viewerToolData.viewerPicture ← ViewerOps.CreateViewer[
flavor: $SolidWindow,
info: [
parent: viewerToolData.outer,
wx: 0, wy: viewerToolData.height,
ww: viewerToolData.outer.ww,
wh: viewerToolData.outer.wh, -- only initial values for ww and wh. They are constrained below
data: viewerToolData, -- contains the current scene
scrollable: FALSE
]
];
Containers.ChildXBound[viewerToolData.outer, viewerToolData.viewerPicture];
Containers.ChildYBound[viewerToolData.outer, viewerToolData.viewerPicture];
viewerToolData.height ← viewerToolData.height + viewerToolData.viewerPicture.wh;
}; -- end of BuildDrawSection
ReloadTipTable: PUBLIC PROC [viewerToolData: ViewerToolData] = TRUSTED {
newTable: TIPUser.TIPTable;
editToolData: EditToolData ← NARROW[viewerToolData.editToolData];
solidviewer: ViewerClasses.Viewer;
bad: BOOLFALSE;
tableName, msg: Rope.ROPE;
SVError.AppendHerald["Reloading tip table...", TRUE];
tableName ← Rope.Concat[editToolData.originalWorkingDirectory, "Solidviews.TIP"];
newTable ← TIPUser.InstantiateNewTIPTable[tableName
! FS.Error => {
bad ← TRUE;
msg ← Rope.Concat["Cannot read TIP table file: ", tableName];
CONTINUE};
TIPUser.InvalidTable => {
bad ← TRUE;
msg ← Rope.Concat["Error(s) saved on TIP.Errors for: ", tableName];
CONTINUE}];
IF bad THEN {SVError.Append[msg, TRUE, TRUE]; RETURN};
SVError.AppendHerald["Done.", FALSE];
IF newTable = NIL THEN ERROR;
solidviewer ← viewerToolData.viewerPicture;
solidviewer.tipTable ← newTable;
};
Init[];
END.