-- File: SVViewerUserImplA.mesa -- Last edited by Bier on July 7, 1983 11:28 am -- Author: Eric Bier in October 1982 -- Contents: Code to respond to button presses made in an SVViewer DIRECTORY BitMap3d, CastRays, CGDevice, Containers, CoordSys, CSG, CSGGraphics, DisplayList3d, Draw3d, Graphics, GraphicsBasic, GraphicsColor, IO, Matrix3d, Menus, MessageWindow, Preprocess3d, Real, Rope, SV2d, SVBoundBox, SVEditUser, SVFiles, SVVector3d, SVViewerTool, SVViewerTools, SVViewerUser, System, TFI3d, TFO3d, Time, ViewerClasses, ViewerOps, ViewerTools; SVViewerUserImplA: CEDAR PROGRAM IMPORTS BitMap3d, CastRays, CoordSys, DisplayList3d, Draw3d, Graphics, IO, Matrix3d, MessageWindow, Preprocess3d, Real, Rope, SVEditUser, SVFiles, SVViewerTools, SVViewerUser, TFI3d, TFO3d, Time, ViewerOps, ViewerTools EXPORTS GraphicsBasic, SVViewerUser = BEGIN Assembly: TYPE = DisplayList3d.Assembly; BoundBox: TYPE = SVBoundBox.BoundBox; Camera: TYPE = CSGGraphics.Camera; Color: TYPE = GraphicsColor.Color; CoordSysGenerator: TYPE = DisplayList3d.CoordSysGenerator; CoordSystem: TYPE = CoordSys.CoordSystem; CSGTree: TYPE = DisplayList3d.CSGTree; DeviceObject: PUBLIC TYPE = CGDevice.Rep; DrawStyle: TYPE = CSGGraphics.DrawStyle; EditToolData: TYPE = SVEditUser.EditToolData; MasterObject: TYPE = DisplayList3d.MasterObject; Matrix4by4: TYPE = Matrix3d.Matrix4by4; MouseButton: TYPE = Menus.MouseButton; Point2d: TYPE = SV2d.Point2d; Primitive: TYPE = CSG.Primitive; Scene: TYPE = DisplayList3d.Scene; Vector: TYPE = SVVector3d.Vector; Viewer: TYPE = ViewerClasses.Viewer; ViewerToolData: TYPE = REF ViewerToolDataObj; ViewerToolDataObj: TYPE = SVViewerTool.ViewerToolDataObj; ViewerTextData: TYPE = SVViewerTool.ViewerTextData; ViewerPictureData: TYPE = REF ViewerPictureDataObj; ViewerPictureDataObj: TYPE = SVViewerUser.ViewerPictureDataObj; InteractionMode: TYPE = SVViewerUser.InteractionMode; -- {select, cast}; DCProc: TYPE = SVViewerUser.DCProc; 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]; }; DrawSceneEtc: PUBLIC PROC [dc: Graphics.Context, viewerToolData: ViewerToolData] = TRUSTED { -- may also draw coordinate systems, drawing planes, etc depending on the current selected modes. viewerPictureData: ViewerPictureData _ NARROW[viewerToolData.viewerPicture.data]; scene: Scene _ viewerPictureData.scene; camera: Camera _ viewerPictureData.camera; IF viewerPictureData.doubleBuffer THEN { BitMap3d.Erase[viewerPictureData.altDC]; DisplayList3d.DrawScene[viewerPictureData.altDC.dc, scene, camera]; IF viewerPictureData.showCoordSys THEN DrawAllCS[viewerPictureData.altDC.dc, viewerToolData]; SVEditUser.DrawAnySelections[dc, viewerToolData]; BitMap3d.DrawAltDisplayContext[dc, viewerPictureData.altDC]; } ELSE { editToolData: EditToolData _ NARROW[viewerToolData.editToolData]; assem: Assembly; success: BOOL; DisplayList3d.DrawScene[dc, scene, camera]; Graphics.SetColor[dc, GraphicsColor.black]; -- IF viewerPictureData.showCoordSys THEN DrawAllCS[dc, viewerToolData]; IF viewerPictureData.showCoordSys THEN IF editToolData.sceneSection.currentScene = scene THEN { [assem, success] _ SVEditUser.GetAssembly[editToolData.sceneSection.assemblyName, scene]; IF success THEN DrawOneCS[dc, viewerToolData, assem.coordSys]; }; SVEditUser.DrawAnySelections[dc, viewerToolData]; }; }; EraseAndDrawSceneEtc: PUBLIC PROC [dc: Graphics.Context, viewerToolData: ViewerToolData] = TRUSTED { -- may also draw coordinate systems, drawing planes, etc depending on the current selected modes. viewerPictureData: ViewerPictureData _ NARROW[viewerToolData.viewerPicture.data]; scene: Scene _ viewerPictureData.scene; camera: Camera _ viewerPictureData.camera; IF viewerPictureData.doubleBuffer THEN { BitMap3d.Erase[viewerPictureData.altDC]; DisplayList3d.DrawScene[viewerPictureData.altDC.dc, scene, camera]; IF viewerPictureData.showCoordSys THEN DrawAllCS[viewerPictureData.altDC.dc, viewerToolData]; SVEditUser.DrawAnySelections[dc, viewerToolData]; BitMap3d.DrawAltDisplayContext[dc, viewerPictureData.altDC]; } ELSE { Graphics.SetColor[dc, GraphicsColor.white]; Graphics.DrawBox[dc, Graphics.GetBounds[dc]]; DisplayList3d.DrawScene[dc, scene, camera]; Graphics.SetColor[dc, GraphicsColor.black]; IF viewerPictureData.showCoordSys THEN DrawAllCS[dc, viewerToolData]; SVEditUser.DrawAnySelections[dc, viewerToolData]; }; }; DrawAllCS: PUBLIC PROC [dc: Graphics.Context, viewerToolData: ViewerToolData] = TRUSTED { viewerPictureData: ViewerPictureData _ NARROW[viewerToolData.viewerPicture.data]; scene: Scene _ viewerPictureData.scene; camera: Camera _ viewerPictureData.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 Draw3d.DrawCoordSys[dc, mat, camera]; ENDLOOP; }; DrawOneCS: PUBLIC PROC [dc: Graphics.Context, viewerToolData: ViewerToolData, cs: CoordSystem] = TRUSTED { viewerPictureData: ViewerPictureData _ NARROW[viewerToolData.viewerPicture.data]; camera: Camera _ viewerPictureData.camera; -- assume that cs has valid cs.wrtCamera and cs.wrtWorld fields. Draw3d.DrawCoordSys[dc, cs.wrtCamera, camera]; }; UpdateHeader: PUBLIC PROC [pictureFile: Rope.ROPE, viewerToolData: ViewerToolData] = TRUSTED { viewerPictureData: ViewerPictureData _ NARROW[viewerToolData.viewerPicture.data]; headerRope: Rope.ROPE; aisName: Rope.ROPE; IF pictureFile = NIL THEN pictureFile _ viewerPictureData.scene.name; headerRope _ Rope.Concat["Solid Scene: ", pictureFile]; aisName _ Rope.Concat[SVFiles.FilenameMinusExtension[pictureFile], ".ais"]; viewerToolData.outer.name _ headerRope; ViewerTools.SetContents[viewerToolData.textSection.ais, aisName, TRUE]; ViewerOps.PaintViewer[viewerToolData.outer, caption, FALSE, NIL]; }; NotifyOfSplit: PUBLIC PROC [viewer: Viewer] = TRUSTED { viewerToolData: ViewerToolData _ NARROW[viewer.data]; viewerPictureData: ViewerPictureData _ NARROW[viewerToolData.viewerPicture.data]; UpdateHeader[viewerPictureData.scene.name, viewerToolData]; }; UnSplit: PUBLIC PROC [viewerToolData: ViewerToolData] = TRUSTED { viewerPictureData: ViewerPictureData _ NARROW[viewerToolData.viewerPicture.data]; UpdateHeader[viewerPictureData.scene.name, viewerToolData]; }; DrawOneCSInViewer: PUBLIC PROC [viewerToolData: ViewerToolData, cs: CoordSystem] = TRUSTED { DoDrawOneCSInViewer: PROC [dc: Graphics.Context] = TRUSTED { DrawOneCS[dc, viewerToolData, cs]; }; Painter[DoDrawOneCSInViewer, viewerToolData]; }; Painter: PUBLIC PROC [proc: DCProc, viewerToolData: ViewerToolData _ NIL] = TRUSTED { viewerPictureData: ViewerPictureData _ NARROW[viewerToolData.viewerPicture.data]; scene: Scene _ viewerPictureData.scene; camera: Camera _ viewerPictureData.camera; viewerPictureData.proc _ proc; ViewerOps.PaintViewer[viewer: viewerToolData.viewerPicture, hint: client, whatChanged: viewerToolData, clearClient: FALSE]; }; -- end of Painter DrawScene: 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]; viewerPictureData: ViewerPictureData _ NARROW[viewerToolData.viewerPicture.data]; DoDrawScene: PROC [dc: Graphics.Context] = TRUSTED { DrawSceneEtc[dc, viewerToolData]; }; Painter[DoDrawScene, viewerToolData]; }; DrawSceneInternal: PUBLIC PROC [parent: REF ANY, clientData: REF ANY, mouseButton: MouseButton, shift, control: BOOL] = TRUSTED {-- like DrawScene but erases the screen before drawing. -- Menus.MenuProc -- viewer is a SolidWindow. clientData is viewerToolData viewerToolData: ViewerToolData _ NARROW[clientData]; DoDrawScene: PROC [dc: Graphics.Context] = TRUSTED { EraseAndDrawSceneEtc[dc, viewerToolData]; }; Painter[DoDrawScene, viewerToolData]; }; 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; viewerPictureData: ViewerPictureData _ NARROW[viewer.data]; screenCS: CoordSystem; camera: Camera _ viewerPictureData.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]; CoordSys.TPlaceAwrtB[screenCS,camera.coordSys,transMat]; }; -- end of PlaceOrigin ResizeBitMap: PUBLIC PROC [viewer: Viewer] = TRUSTED { -- viewer is the viewerPicture -- resize its bitMap viewerPictureData: ViewerPictureData _ NARROW[viewer.data]; BitMap3d.ResizeBitMap[viewer, viewerPictureData.altDC]; }; 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]; viewerPictureData: ViewerPictureData _ NARROW[viewerToolData.viewerPicture.data]; oldScene: Scene _ viewerPictureData.scene; viewerPictureData.scene _ DisplayList3d.CreateScene["NoName.pic"]; UpdateHeader[viewerPictureData.scene.name, viewerToolData]; ViewerTools.SetContents[viewerToolData.textSection.fileName, viewerPictureData.scene.name]; SVViewerUser.Selected[parent, clientData, mouseButton, shift, control]; Erase[parent, clientData, mouseButton, shift, control]; SVEditUser.NotifyOfEmpty[viewerToolData: viewerToolData, from: oldScene, to: viewerPictureData.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 }; ConfirmEmpty: PUBLIC PROC [parent: REF ANY, clientData: REF ANY, mouseButton: MouseButton, shift, control: BOOL] = TRUSTED { viewerToolData: ViewerToolData _ NARROW[clientData]; viewerPictureData: ViewerPictureData _ NARROW[viewerToolData.viewerPicture.data]; scene: Scene _ viewerPictureData.scene; picName: Rope.ROPE _ ViewerTools.GetContents[viewerToolData.textSection.fileName]; stream: IO.STREAM; rope: Rope.ROPE; dirty: BOOL; stream _ IO.CreateOutputStreamToRope[]; dirty _ viewerToolData.outer.newVersion; IF dirty THEN stream.PutF["Confirm discard of edits"] ELSE stream.PutF["Confirm emptying of viewer"]; rope _ IO.GetOutputStreamRope[stream]; MessageWindow.Append[rope, TRUE]; }; ClearScene: PUBLIC PROC [parent: REF ANY, clientData: REF ANY, mouseButton: MouseButton, shift, control: BOOL] = TRUSTED { viewerToolData: ViewerToolData _ NARROW[clientData]; viewerPictureData: ViewerPictureData _ NARROW[viewerToolData.viewerPicture.data]; DisplayList3d.ClearScene[viewerPictureData.scene]; }; Erase: PUBLIC PROC [parent: REF ANY, clientData: REF ANY, mouseButton: MouseButton, shift, control: BOOL] = TRUSTED { viewerToolData: ViewerToolData _ NARROW[clientData]; viewerPictureData: ViewerPictureData _ NARROW[viewerToolData.viewerPicture.data]; 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]; }; 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]; viewerPictureData: ViewerPictureData _ NARROW[viewerToolData.viewerPicture.data]; scene: Scene _ viewerPictureData.scene; camera: Camera _ viewerPictureData.camera; tree: CSG.CSGTree; DoDrawBoundBoxes: PROC [dc: Graphics.Context] = TRUSTED { Draw3d.DrawBoundBoxes[dc, tree, camera]; }; tree _ DisplayList3d.SceneToTree[scene, camera]; -- does a TellAboutCameraAndWorld [] _ Preprocess3d.Preprocess[tree, camera]; Painter[DoDrawBoundBoxes, viewerToolData]; }; -- end of DrawBoundBoxes SceneNewVersion: PUBLIC PROC [viewerToolData: ViewerToolData] = TRUSTED { viewerPictureData: ViewerPictureData _ NARROW[viewerToolData.viewerPicture.data]; scene: Scene _ viewerPictureData.scene; SVEditUser.SceneNewVersion[viewerToolData, scene]; }; NewVersion: PUBLIC PROC [viewer: Viewer] = TRUSTED { viewerToolData: ViewerToolData _ NARROW[viewer.data]; viewerPictureData: ViewerPictureData _ NARROW[viewerToolData.viewerPicture.data]; scene: Scene _ viewerPictureData.scene; scene.dirty _ TRUE; viewerToolData.outer.newVersion _ TRUE; UpdateHeader[scene.name, viewerToolData]; }; SceneOldVersion: PUBLIC PROC [viewerToolData: ViewerToolData] = TRUSTED { viewerPictureData: ViewerPictureData _ NARROW[viewerToolData.viewerPicture.data]; scene: Scene _ viewerPictureData.scene; SVEditUser.SceneOldVersion[viewerToolData, scene]; }; OldVersion: PUBLIC PROC [viewer: Viewer] = TRUSTED { viewerToolData: ViewerToolData _ NARROW[viewer.data]; viewerPictureData: ViewerPictureData _ NARROW[viewerToolData.viewerPicture.data]; scene: Scene _ viewerPictureData.scene; scene.dirty _ FALSE; viewerToolData.outer.newVersion _ FALSE; UpdateHeader[scene.name, viewerToolData]; }; Reset: PUBLIC PROC [parent: REF ANY, clientData: REF ANY, mouseButton: MouseButton, shift, control: BOOL] = TRUSTED { viewerToolData: ViewerToolData _ NARROW[clientData]; viewerPictureData: ViewerPictureData _ NARROW[viewerToolData.viewerPicture.data]; success: BOOL; scene: Scene _ viewerPictureData.scene; [scene, success] _ SVEditUser.LoadScene[viewerToolData, scene.name]; -- Reload this scene from its backing file. IF success THEN {viewerPictureData.scene _ scene; SceneOldVersion[viewerToolData]; UpdateHeader[scene.name, viewerToolData]; DrawSceneInternal[parent, clientData, mouseButton, shift, control]; 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]; viewerPictureData: ViewerPictureData _ NARROW[viewerToolData.viewerPicture.data]; scene: Scene _ viewerPictureData.scene; stream: IO.STREAM; rope: Rope.ROPE; dirty: BOOL; stream _ IO.CreateOutputStreamToRope[]; dirty _ viewerToolData.outer.newVersion; IF dirty THEN stream.PutF["Confirm discard of edits"] ELSE stream.PutF["Confirm reset of %g", [rope[scene.name]]]; rope _ IO.GetOutputStreamRope[stream]; MessageWindow.Append[rope, TRUE]; }; -- end of ConfirmReset Save: PUBLIC PROC [parent: REF ANY, clientData: REF ANY, mouseButton: MouseButton, shift, control: BOOL] = TRUSTED { viewerToolData: ViewerToolData _ NARROW[clientData]; viewerPictureData: ViewerPictureData _ NARROW[viewerToolData.viewerPicture.data]; success: BOOL; scene: Scene _ viewerPictureData.scene; success _ SVEditUser.SaveScene[viewerToolData, scene.name]; 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]; viewerPictureData: ViewerPictureData _ NARROW[viewerToolData.viewerPicture.data]; scene: Scene _ viewerPictureData.scene; exists: BOOL; stream: IO.STREAM; rope: Rope.ROPE; stream _ IO.CreateOutputStreamToRope[]; exists _ SVFiles.FileExists[scene.name]; IF exists THEN stream.PutF["Confirm Save to %g [Old File]", [rope[scene.name]]] ELSE {stream.PutF["%g doesn't exist. Use Store", [rope[scene.name]]]; MessageWindow.Blink[] }; rope _ IO.GetOutputStreamRope[stream]; MessageWindow.Append[rope, TRUE]; }; Load: PUBLIC PROC [parent: REF ANY, clientData: REF ANY, mouseButton: MouseButton, shift, control: BOOL] = TRUSTED { viewerToolData: ViewerToolData _ NARROW[clientData]; viewerPictureData: ViewerPictureData _ NARROW[viewerToolData.viewerPicture.data]; success: BOOL; picName: Rope.ROPE _ ViewerTools.GetContents[viewerToolData.textSection.fileName]; scene: Scene; [scene, success] _ SVEditUser.LoadScene[viewerToolData, picName]; IF success THEN {viewerPictureData.scene _ scene; SceneOldVersion[viewerToolData]; UpdateHeader[picName, viewerToolData]; DrawSceneInternal[parent, clientData, mouseButton, shift, control]; SVViewerUser.Selected[parent, clientData, mouseButton, shift, control]; }; }; -- end of Load ConfirmLoad: PUBLIC PROC [parent: REF ANY, clientData: REF ANY, mouseButton: MouseButton, shift, control: BOOL] = TRUSTED { viewerToolData: ViewerToolData _ NARROW[clientData]; viewerPictureData: ViewerPictureData _ NARROW[viewerToolData.viewerPicture.data]; scene: Scene _ viewerPictureData.scene; picName: Rope.ROPE _ ViewerTools.GetContents[viewerToolData.textSection.fileName]; stream: IO.STREAM; rope: Rope.ROPE; dirty: BOOL; stream _ IO.CreateOutputStreamToRope[]; dirty _ viewerToolData.outer.newVersion; IF dirty THEN stream.PutF["Confirm discard of edits"] ELSE stream.PutF["Confirm load of %g", [rope[picName]]]; rope _ IO.GetOutputStreamRope[stream]; MessageWindow.Append[rope, TRUE]; }; -- end of ConfirmLoad Store: PUBLIC PROC [parent: REF ANY, clientData: REF ANY, mouseButton: MouseButton, shift, control: BOOL] = TRUSTED { viewerToolData: ViewerToolData _ NARROW[clientData]; viewerPictureData: ViewerPictureData _ NARROW[viewerToolData.viewerPicture.data]; success: BOOL; picName: Rope.ROPE _ ViewerTools.GetContents[viewerToolData.textSection.fileName]; scene: Scene _ viewerPictureData.scene; success _ SVEditUser.StoreScene[viewerToolData, scene, picName]; IF success THEN {UpdateHeader[picName, viewerToolData]; SVViewerUser.Selected[parent, clientData, mouseButton, shift, control]; SceneOldVersion[viewerToolData]; UpdateHeader[scene.name, viewerToolData];}; }; -- end of Store ConfirmStore: PUBLIC PROC [parent: REF ANY, clientData: REF ANY, mouseButton: MouseButton, shift, control: BOOL] = TRUSTED { viewerToolData: ViewerToolData _ NARROW[clientData]; viewerPictureData: ViewerPictureData _ NARROW[viewerToolData.viewerPicture.data]; scene: Scene _ viewerPictureData.scene; picName: Rope.ROPE _ ViewerTools.GetContents[viewerToolData.textSection.fileName]; exists: BOOL; stream: IO.STREAM; rope: Rope.ROPE; stream _ IO.CreateOutputStreamToRope[]; exists _ SVFiles.FileExists[picName]; IF exists THEN stream.PutF["Confirm Store of %g [Old File]", [rope[picName]]] ELSE stream.PutF["Confirm Store to %g [New File]", [rope[picName]]]; rope _ IO.GetOutputStreamRope[stream]; MessageWindow.Append[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]; viewerPictureData: ViewerPictureData _ NARROW[viewerToolData.viewerPicture.data]; scene: Scene _ viewerPictureData.scene; SVEditUser.Split[viewerToolData, scene]; }; RayCast: PUBLIC PROC [parent: REF ANY, clientData: REF ANY, mouseButton: MouseButton, shift, control: BOOL] = TRUSTED { viewerToolData: ViewerToolData _ NARROW[clientData]; viewerPictureData: ViewerPictureData _ NARROW[viewerToolData.viewerPicture.data]; editToolData: EditToolData _ NARROW[viewerToolData.editToolData]; scene: Scene _ viewerPictureData.scene; camera: Camera _ viewerPictureData.camera; tree: CSGTree; startTime: System.GreenwichMeanTime; endTime: System.GreenwichMeanTime; totalTime: LONG CARDINAL; timeStream: IO.STREAM _ IO.CreateOutputStreamToRope[]; outStream: IO.STREAM _ SVEditUser.GetOutHandle[]; timeRope: Rope.ROPE; aisFileRope: Rope.ROPE _ ViewerTools.GetContents[viewerToolData.textSection.ais]; resolution: REAL _ SVViewerTools.GetReal[editToolData.cameraSection.resolution, 72.0]; -- For now, I delete any old file if it exists. startTime _ Time.Current[]; tree _ DisplayList3d.SceneToTree[scene, camera]; CastRays.DrawTree[NIL, tree, scene.lightSources, viewerPictureData.camera, aisFileRope, mouseButton = blue, resolution, SVViewerUser.RayCastProgress, viewerToolData, outStream]; endTime _ Time.Current[]; totalTime _ endTime - startTime; outStream.PutF[" Raycast took (%r)\n",[cardinal[totalTime]]]; timeStream.PutF[" Raycast took (%r)",[cardinal[totalTime]]]; timeRope _ IO.GetOutputStreamRope[timeStream]; MessageWindow.Append[timeRope, 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"]; stream: IO.STREAM; rope: Rope.ROPE; stream _ IO.CreateOutputStreamToRope[]; IF mouseButton = blue THEN { -- black and white only exists _ SVFiles.FileExists[aisFileRope]; stream.PutF["Confirm raycast to %g.", [rope[aisFileRope]]]; IF exists THEN stream.PutF[" [Old File]"] ELSE stream.PutF[" [New File]"]; } ELSE { exists _ SVFiles.FileExists[aisFileRope] OR SVFiles.FileExists[redRope] OR SVFiles.FileExists[greenRope] OR SVFiles.FileExists[blueRope]; stream.PutF["Confirm raycast to %g [-red, -green, -blue, plain].ais", [rope[SVFiles.FilenameMinusExtension[aisFileRope]]]]; IF exists THEN stream.PutF[" [Old Files]"] ELSE stream.PutF[" [New Files]"]; }; rope _ IO.GetOutputStreamRope[stream]; MessageWindow.Append[rope, TRUE]; }; Stop: PUBLIC PROC [parent: REF ANY, clientData: REF ANY, mouseButton: MouseButton, shift, control: BOOL] = TRUSTED { viewerToolData: ViewerToolData _ NARROW[clientData]; viewerPictureData: ViewerPictureData _ NARROW[viewerToolData.viewerPicture.data]; camera: Camera _ viewerPictureData.camera; camera.abort _ TRUE; }; ARay: PUBLIC PROC [parent: REF ANY, clientData: REF ANY, mouseButton: MouseButton, shift, control: BOOL] = TRUSTED { viewerToolData: ViewerToolData _ NARROW[clientData]; viewerPictureData: ViewerPictureData _ NARROW[viewerToolData.viewerPicture.data]; scene: Scene _ viewerPictureData.scene; camera: Camera _ viewerPictureData.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 _ DisplayList3d.SceneToTree[scene, camera]; color: Color; [x, y] _ ReadTwoReals[viewerToolData.textSection.xyz]; xInt _ Real.FixI[x]; yInt _ Real.FixI[y]; outHandle _ SVEditUser.GetOutHandle[]; color _ CastRays.SingleRay[xInt, yInt, tree, scene.lightSources, viewerPictureData.camera, TRUE, outHandle]; outHandle.PutF["[%g,%g]: ",[real[x]], [real[y]]]; TFO3d.FileoutColor[outHandle, color]; }; -- end of ARay END. Ę ˜JšįĪc¸œĪk œ;žœUžœ†žœžœžœ@žœ“žœ!žœ žœ%žœ žœžœ+žœ1žœ"žœ(žœžœžœ(žœ*žœ+žœ%žœžœžœžœžœ žœžœ*žœžœ'žœ5žœ5žœžœ-žœ9žœ!œ žœĪn œžœžœžœžœžœžœ6žœžœžœžœ Ÿ œžœžœ:žœaœ)žœ{žœ žœvžœ#žœąžœ"žœ=žœ`Iœžœ žœžœ0žœežœ žœwŸœžœžœ:žœaœ)žœ{žœ žœvžœ#žœąžœŋžœ žœ_Ÿ œžœžœ:žœ+žœĐžœQžœžœžœ>4œ)žœŸ œžœžœKžœ+žœRAœ5Ÿ œžœžœžœ$žœ+žœ7žœžœžœžœžœžžœ9žœžœ Ÿ œžœžœžœ%žœ7žœgŸœžœžœ$žœ+žœhŸœžœžœ5žœŸœžœžœbŸœžœžœ1žœžœ+žœ§žœœŸ œžœžœ žœžœžœžœ,žœžœœ9œ"žœ6žœ&Ÿ œžœžœYŸœžœžœ žœžœžœžœ,žœžœ8œœ9œ"žœŸ œžœžœaŸ œžœžœžœœCœžœAžœ† œ!œ&œ’œŸ œžœžœžœœœ(žœMŸœžœžœ žœžœžœžœ,žœžœ4œ"žœ6žœģ›œŸ œžœžœ žœžœžœžœ,žœžœ%žœ6žœ]žœJžœžœžœ žœ žœHžœžœ-žœ4žœ:žœ Ÿ œžœžœ žœžœžœžœ,žœžœ%žœ6žœ_Ÿœžœžœ žœžœžœžœ,žœžœ%žœ6žœ&ŸœžœžœúŸœžœžœ žœžœžœžœ,žœžœ%žœŸœžœžœYŸœžœžœ žœžœžœžœ,žœžœœ"žœ6žœžœ Ÿœžœžœf"œ]œŸœžœžœ$žœ+žœ‡Ÿ œžœžœžœ%žœ7žœ]žœ%žœ3Ÿœžœžœ$žœ+žœˆŸ œžœžœžœ%žœ7žœ]žœ%žœ2Ÿœžœžœ žœžœžœžœ,žœžœ%žœ6žœ/žœr,œžœ žœ‹Ÿœžœžœ žœžœžœžœ,žœžœ%žœ6žœWžœžœžœ žœ žœHžœžœ-žœAžœ:žœœŸœžœžœ žœžœžœžœ,žœžœ%žœ6žœ/žœižœ žœĨœŸ œžœžœ žœžœžœžœ,žœžœ%žœ6žœWžœ žœžœžœ žœHžœžœFžœgžœ:žœ Ÿœžœžœ žœžœžœžœ,žœžœ%žœ6žœ/žœžœ”žœ žœˆœŸ œžœžœ žœžœžœžœ,žœžœ%žœ6žœ]žœJžœžœžœ žœ žœHžœžœ-žœ=žœ:žœœŸœžœžœ žœžœžœžœ,žœžœ%žœ6žœ/žœžœ­žœ žœČœŸ œžœžœ žœžœžœžœ,žœžœ%žœ6žœ]žœJžœ žœžœžœ žœEžœžœDžœIžœ:žœ Ÿœžœžœ žœžœžœžœ,žœžœgœ"žœ6žœ~Ÿœžœžœ žœžœžœžœ,žœžœ%žœ6žœCžœÚžœžœžœžœžœ)žœžœ.žœžœIžœH0œbžœãžœBžœYœŸœžœžœ žœžœžœžœ,žœžœ%žœžœžœKžœZžœ[žœSžœžœžœ žœžœžœœlžœžœžœ"žœ.žœžœžœ žœžœžœ+žœ:žœ Ÿœžœžœ žœžœžœžœ,žœžœ%žœ6žœažœŸœžœžœ žœžœžœžœ,žœžœ%žœ6žœ{_œžœžœžœžœŧžœlœžœ˜ž—…—_h&