-- File: SVViewerUserImplB.mesa -- Last edited by Bier on June 28, 1983 5:05 pm -- Author: Eric Bier in October 1982 -- Contents: Code to respond to button presses made in an SVViewer DIRECTORY AIS, BandsClient, Buttons, CastRays, CGDevice, ColorMap, Containers, CoordSys, CSG, CSGGraphics, DisplayList3d, DitherAIS, Draw3d, FileIO, Graphics, GraphicsBasic, GraphicsColor, GraphicsToPress, IO, Labels, Map, Matrix3d, Menus, MessageWindow, Preprocess3d, Real, Rope, SV2d, SVBoundBox, SVEditUser, SVFiles, SVImage, SVTransforms, SVVector3d, SVViewerTool, SVViewerTools, SVViewerUser, System, TFO3d, Time, ViewerClasses, ViewerTools; SVViewerUserImplB: CEDAR PROGRAM IMPORTS AIS, BandsClient, Buttons, CastRays, ColorMap, CoordSys, CSGGraphics, DisplayList3d, DitherAIS, Draw3d, FileIO, Graphics, GraphicsToPress, IO, Labels, Map, Matrix3d, MessageWindow, Preprocess3d, Real, Rope, SVBoundBox, SVEditUser, SVFiles, SVImage, SVTransforms, SVViewerUser, SVViewerTools, TFO3d, Time, 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; CSGTree: TYPE = DisplayList3d.CSGTree; DeviceObject: PUBLIC TYPE = CGDevice.Rep; DeviceType: TYPE = BandsClient.DeviceType; DrawStyle: TYPE = CSGGraphics.DrawStyle; EditToolData: TYPE = SVEditUser.EditToolData; FrameBox: TYPE = CSGGraphics.FrameBox; MasterObject: TYPE = DisplayList3d.MasterObject; Matrix4by4: TYPE = Matrix3d.Matrix4by4; MouseButton: TYPE = Menus.MouseButton; Point2d: TYPE = SV2d.Point2d; Primitive: TYPE = CSG.Primitive; Scene: TYPE = DisplayList3d.Scene; Selection: TYPE = SVEditUser.Selection; 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; -- GLOBAL VARIABLES globalTable: Map.ColorTable; globalSceneStyleCount: NAT = 3; globalSceneStyleArray: ARRAY[1..globalSceneStyleCount] OF Rope.ROPE _ ["WireFrame", "Shaded", "Normals"]; globalBandsDeviceCount: NAT = 3; globalBandsDeviceArray: ARRAY[1..globalBandsDeviceCount] OF Rope.ROPE _ ["Hornet", "Screen", "Platemaker"]; Press: 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; -- TIMING VARABLES startTime: System.GreenwichMeanTime; endTime: System.GreenwichMeanTime; totalTime: LONG CARDINAL; timeStream: IO.STREAM; outStream: IO.STREAM _ SVEditUser.GetOutHandle[]; timeRope: Rope.ROPE; -- PRESS VARIABLES pressName: Rope.ROPE; pressStream: IO.STREAM; pressContext: Graphics.Context; -- START TIMING startTime _ Time.Current[]; -- START PRESSING pressName _ ViewerTools.GetContents[viewerToolData.textSection.ais]; pressName _ Rope.Concat[SVFiles.FilenameMinusExtension[pressName], ".press"]; pressStream _ FileIO.Open[pressName, overwrite, none]; pressContext _ GraphicsToPress.NewContextFromStream[ outputStream: pressStream, fileNameForHeaderPage: pressName, resolution: 384]; CSGGraphics.SetQualityCamera[camera, quality]; -- make a high quality image CSGGraphics.ColorFilmCamera[camera, FALSE]; -- but only black and white SVViewerUser.DrawSceneEtc[pressContext, viewerToolData]; CSGGraphics.ColorFilmCamera[camera, TRUE]; -- restore to color mode CSGGraphics.SetQualityCamera[camera, fast]; -- restore to fast mode for interactive editting GraphicsToPress.Close[pressContext]; endTime _ Time.Current[]; totalTime _ endTime - startTime; timeStream _ IO.CreateOutputStreamToRope[]; timeStream.PutF[" Done. Pressing took (%r)",[cardinal[totalTime]]]; outStream.PutF[" Done. Pressing took (%r)",[cardinal[totalTime]]]; timeRope _ timeStream.GetOutputStreamRope[]; MessageWindow.Append[timeRope, TRUE]; }; PressAIS: 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; minX, minY, maxX, maxY: REAL; tree: CSGTree; aisRope: Rope.ROPE _ ViewerTools.GetContents[viewerToolData.textSection.ais]; -- TIMING VARABLES startTime: System.GreenwichMeanTime; endTime: System.GreenwichMeanTime; totalTime: LONG CARDINAL; timeStream: IO.STREAM; timeRope: Rope.ROPE; -- PRESS VARIABLES pressName: Rope.ROPE; pressStream: IO.STREAM; outStream: IO.STREAM _ SVEditUser.GetOutHandle[]; pressContext: Graphics.Context; -- START TIMING startTime _ Time.Current[]; -- START PRESSING pressName _ ViewerTools.GetContents[viewerToolData.textSection.ais]; pressName _ Rope.Concat[SVFiles.FilenameMinusExtension[pressName], ".press"]; pressStream _ FileIO.Open[pressName, overwrite, none]; pressContext _ GraphicsToPress.NewContextFromStream[ outputStream: pressStream, fileNameForHeaderPage: pressName, resolution: 384]; tree _ DisplayList3d.SceneToTree[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 _ Time.Current[]; totalTime _ endTime - startTime; timeStream _ IO.CreateOutputStreamToRope[]; timeStream.PutF[" Done. Pressing AIS took (%r)",[cardinal[totalTime]]]; outStream.PutF[" Done. Pressing AIS took (%r)",[cardinal[totalTime]]]; timeRope _ timeStream.GetOutputStreamRope[]; MessageWindow.Append[timeRope, TRUE]; }; PressBWAIS: 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; minX, minY, maxX, maxY: REAL; tree: CSGTree; aisRope: Rope.ROPE _ ViewerTools.GetContents[viewerToolData.textSection.ais]; -- TIMING VARABLES startTime: System.GreenwichMeanTime; endTime: System.GreenwichMeanTime; totalTime: LONG CARDINAL; timeStream: IO.STREAM; timeRope: Rope.ROPE; -- PRESS VARIABLES pressName: Rope.ROPE; pressStream: IO.STREAM; outStream: IO.STREAM _ SVEditUser.GetOutHandle[]; pressContext: Graphics.Context; -- START TIMING startTime _ Time.Current[]; -- START PRESSING pressName _ ViewerTools.GetContents[viewerToolData.textSection.ais]; pressName _ Rope.Concat[SVFiles.FilenameMinusExtension[pressName], ".press"]; pressStream _ FileIO.Open[pressName, overwrite, none]; 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 _ Time.Current[]; totalTime _ endTime - startTime; timeStream _ IO.CreateOutputStreamToRope[]; timeStream.PutF[" Done. Pressing AIS took (%r)",[cardinal[totalTime]]]; outStream.PutF[" Done. Pressing AIS took (%r)",[cardinal[totalTime]]]; timeRope _ timeStream.GetOutputStreamRope[]; MessageWindow.Append[timeRope, TRUE]; }; CrossHairs: PUBLIC PROC [parent: REF ANY, clientData: REF ANY, mouseButton: MouseButton, shift, control: BOOL] = TRUSTED { -- viewer is the crossHairs button viewerToolData: ViewerToolData _ NARROW[clientData]; viewerPictureData: ViewerPictureData _ NARROW[viewerToolData.viewerPicture.data]; camera: Camera _ viewerPictureData.camera; DoCrossHairs: PROC [dc: Graphics.Context] = TRUSTED { Draw3d.Draw2dCoordSys[dc, [0,0], camera]; }; SVViewerUser.Painter[DoCrossHairs, viewerToolData]; }; -- end of CrossHairs DrawDither: PUBLIC PROC [parent: REF ANY, clientData: REF ANY, mouseButton: MouseButton, shift, control: BOOL] = TRUSTED { -- parent is the DrawDither button viewerToolData: ViewerToolData _ NARROW[clientData]; viewerPictureData: ViewerPictureData _ NARROW[viewerToolData.viewerPicture.data]; scene: Scene _ viewerPictureData.scene; minX, minY, maxX, maxY: REAL; camera: Camera _ viewerPictureData.camera; tree: CSGTree; aisRope: Rope.ROPE _ ViewerTools.GetContents[viewerToolData.textSection.ais]; DoDrawBlackAndWhite: PROC [dc: Graphics.Context] = TRUSTED { SVImage.DrawAndScaleBlackAndWhiteImage[dc, aisRope, [camera.screenCS.mat[1][4], camera.screenCS.mat[2][4]], minX, minY, maxX, maxY]; }; aisRope _ Rope.Concat[SVFiles.FilenameMinusExtension[aisRope], "-std.ais"]; tree _ DisplayList3d.SceneToTree[scene, camera]; [minX, minY, maxX, maxY] _ MinAndMaxFromCameraAndTree[camera, tree]; SVViewerUser.Painter[DoDrawBlackAndWhite, viewerToolData]; }; -- end of DrawDither 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, "-green.ais"]; blueName _ Rope.Concat[baseName, "-blue.ais"]; FSFilename _ Rope.Concat[baseName, "-std.ais"]; BEGIN globalTable _ Preprocess3d.GetGlobalTable[]; DitherAIS.Squash[redName, greenName, blueName, FSFilename, MyMap ! AIS.Error => { outStream: IO.STREAM _ SVEditUser.GetOutHandle[]; outStream.PutF["%g -*.ais - Bad file names", [rope[baseName]]]; MessageWindow.Append[Rope.Concat[baseName, "-*.ais - Bad file names"], TRUE]; GOTO giveUp}]; EXITS giveUp => NULL; END; }; MyMap: DitherAIS.UserMapProc = TRUSTED { rb, gb, bb: Map.ColorMapSize; palix _ Map.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; }; Extend: PUBLIC PROC [parent: REF ANY, clientData: REF ANY, mouseButton: MouseButton, shift, control: BOOL] = TRUSTED { -- Get the edittool to extend the current secondary selection. SVEditUser.ExtendSecondary[]; }; Move: PUBLIC PROC [parent: REF ANY, clientData: REF ANY, mouseButton: MouseButton, shift, control: BOOL] = TRUSTED { newMat: Matrix4by4; primary, secondary: Selection; primary _ SVEditUser.GetPrimarySelection[]; secondary _ SVEditUser.GetSecondarySelection[]; IF primary = NIL THEN RETURN[]; IF primary.assembly = NIL THEN RETURN; IF secondary = NIL THEN RETURN[]; IF secondary.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 primary.viewerToolData # secondary.viewerToolData THEN { primaryPicture: ViewerPictureData _ NARROW[primary.viewerToolData.viewerPicture.data]; secondaryPicture: ViewerPictureData _ NARROW[secondary.viewerToolData.viewerPicture.data]; IF primaryPicture.scene # secondaryPicture.scene THEN { copyAssembly: Assembly _ DisplayList3d.MergeAssemblyIntoScene[secondary.assembly, secondaryPicture.scene, primaryPicture.scene.assembly, primaryPicture.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[primary.viewerToolData]; SVViewerUser.DrawSceneInternal[NIL, primary.viewerToolData, red, FALSE, FALSE]; SVViewerUser.DrawSceneInternal[NIL, secondary.viewerToolData, red, FALSE, FALSE]; RETURN; }; }; newMat _ Matrix3d.MakeRotateYMat[180]; SVTransforms.PlaceIndirect[secondary.assembly, secondary.coordSys, primary.coordSys, newMat]; -- Rotate them so they are tangent in an exterior fashion SVViewerUser.SceneNewVersion[primary.viewerToolData]; SVViewerUser.DrawSceneInternal[NIL, primary.viewerToolData, red, FALSE, FALSE]; }; DrawPt: 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; -- 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 { Draw3d.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; IF frame.fullScreen THEN { boundBox _ Preprocess3d.Preprocess[tree, camera]; 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]; viewerPictureData: ViewerPictureData _ NARROW[viewerToolData.viewerPicture.data]; editToolData: EditToolData _ NARROW[viewerToolData.editToolData]; scene: Scene _ viewerPictureData.scene; resolution: REAL _ SVViewerTools.GetReal[editToolData.cameraSection.resolution, 72.0]; boundBox: BoundBox; minX, minY, maxX, maxY: REAL; camera: Camera _ viewerPictureData.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]; }; tree _ DisplayList3d.SceneToTree[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]; viewerPictureData: ViewerPictureData _ NARROW[viewerToolData.viewerPicture.data]; editToolData: EditToolData _ NARROW[viewerToolData.editToolData]; resolution: REAL _ SVViewerTools.GetReal[editToolData.cameraSection.resolution, 72.0]; scene: Scene _ viewerPictureData.scene; boundBox: BoundBox; minX, minY, maxX, maxY: REAL; camera: Camera _ viewerPictureData.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, FALSE]; }; tree _ DisplayList3d.SceneToTree[scene, camera]; [minX, minY, maxX, maxY] _ MinAndMaxFromCameraAndTree[camera, tree]; boundBox _ SVBoundBox.BoundBoxFromValues[minX, minY, maxX, maxY]; SVViewerUser.Painter[DoDrawBlackAndWhite, viewerToolData]; }; -- end of DrawBlackAndWhite SetFocalLength: PUBLIC PROC [parent: REF ANY, clientData: REF ANY, mouseButton: MouseButton, shift, control: BOOL] = TRUSTED { viewerToolData: ViewerToolData _ NARROW[clientData]; viewerPictureData: ViewerPictureData _ NARROW[viewerToolData.viewerPicture.data]; viewerPictureData.camera.focalLength _ SVViewerTools.GetReal[viewerToolData.textSection.focalLength, 1800]; }; -- end of SetFocalLength MakeBands: 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; deviceType: DeviceType; deviceName: Rope.ROPE; -- TIMING VARABLES startTime: System.GreenwichMeanTime; endTime: System.GreenwichMeanTime; totalTime: LONG CARDINAL; timeStream: IO.STREAM; outStream: IO.STREAM _ SVEditUser.GetOutHandle[]; timeRope: Rope.ROPE; -- BANDS VARIABLES bandContext: Graphics.Context; bandDevice: BandsClient.Device; -- START TIMING startTime _ Time.Current[]; -- START BANDS deviceName _ globalBandsDeviceArray[viewerPictureData.bandsDeviceIndex]; SELECT TRUE FROM Rope.Equal[deviceName, "Hornet"] => deviceType _ hornet; Rope.Equal[deviceName, "Screen"] => deviceType _ screen; Rope.Equal[deviceName, "Platemaker"] => deviceType _ platemaker; ENDCASE => ERROR; BandsClient.SetUpSeparation[none, Tentfilter]; [bandContext, bandDevice] _ BandsClient.OpenBands[deviceType]; CSGGraphics.SetQualityCamera[camera, quality]; -- make a high quality image CSGGraphics.ColorFilmCamera[camera, FALSE]; -- but only black and white SVViewerUser.DrawSceneEtc[bandContext, viewerToolData]; CSGGraphics.ColorFilmCamera[camera, TRUE]; -- restore to color mode CSGGraphics.SetQualityCamera[camera, fast]; -- restore to fast mode for interactive editting BandsClient.CloseBands[bandDevice, deviceType]; endTime _ Time.Current[]; totalTime _ endTime - startTime; timeStream _ IO.CreateOutputStreamToRope[]; timeStream.PutF[" Done. Bands took (%r)",[cardinal[totalTime]]]; outStream.PutF[" Done. Bands took (%r)",[cardinal[totalTime]]]; timeRope _ timeStream.GetOutputStreamRope[]; MessageWindow.Append[timeRope, TRUE]; }; Tentfilter: PROC [x,y: REAL] RETURNS [val: REAL] = TRUSTED { RETURN [1.0-ABS[x]]; }; -- 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]; }; PictureFilePrompt: PUBLIC PROC [parent: REF ANY, clientData: REF ANY, mouseButton: MouseButton, shift, control: BOOL] = TRUSTED { viewerToolData: ViewerToolData _ NARROW[clientData]; ViewerTools.SetSelection[viewerToolData.textSection.fileName]; }; -- PROMPTS WHICH CYCLE THROUGH POSSIBILITIES StylePrompt: PUBLIC PROC [parent: REF ANY, clientData: REF ANY, mouseButton: MouseButton, shift, control: BOOL] = TRUSTED { viewerToolData: ViewerToolData _ NARROW[clientData]; viewerPictureData: ViewerPictureData _ NARROW[viewerToolData.viewerPicture.data]; newStyle: DrawStyle; scene: Scene _ viewerPictureData.scene; viewerPictureData.sceneStyleIndex _ IF viewerPictureData.sceneStyleIndex = globalSceneStyleCount THEN 1 ELSE viewerPictureData.sceneStyleIndex + 1; Labels.Set[viewerToolData.textSection.viewStyle, globalSceneStyleArray[viewerPictureData.sceneStyleIndex]]; SELECT globalSceneStyleArray[viewerPictureData.sceneStyleIndex] FROM "WireFrame" => newStyle _ wire; "Shaded" => newStyle _ shaded; "Normals" => newStyle _ normals; -- "RayCast" => newStyle _ rayCast; ENDCASE => ERROR; viewerPictureData.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]; viewerPictureData: ViewerPictureData _ NARROW[viewerToolData.viewerPicture.data]; IF viewerPictureData.doubleBuffer THEN { viewerPictureData.doubleBuffer _ NOT viewerPictureData.doubleBuffer; Buttons.SetDisplayStyle[button, $BlackOnWhite]; } ELSE {viewerPictureData.doubleBuffer _ NOT viewerPictureData.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]; viewerPictureData: ViewerPictureData _ NARROW[viewerToolData.viewerPicture.data]; IF viewerPictureData.showCoordSys THEN { viewerPictureData.showCoordSys _ NOT viewerPictureData.showCoordSys; Buttons.SetDisplayStyle[button, $BlackOnWhite]; } ELSE {viewerPictureData.showCoordSys _ NOT viewerPictureData.showCoordSys; Buttons.SetDisplayStyle[button, $WhiteOnBlack]; }; }; -- end of ShowCoordsMode -- OPTIONS LISTERS BandsDevice: PUBLIC PROC [parent: REF ANY, clientData: REF ANY, mouseButton: MouseButton, shift, control: BOOL] = TRUSTED { viewerToolData: ViewerToolData _ NARROW[clientData]; thisButton: Viewer _ NARROW[parent]; viewerPictureData: ViewerPictureData _ NARROW[viewerToolData.viewerPicture.data]; scene: Scene _ viewerPictureData.scene; viewerPictureData.bandsDeviceIndex _ IF viewerPictureData.bandsDeviceIndex = globalBandsDeviceCount THEN 1 ELSE viewerPictureData.bandsDeviceIndex + 1; Buttons.ReLabel[thisButton, globalBandsDeviceArray[viewerPictureData.bandsDeviceIndex]]; }; -- 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]; viewerToolData.textSection.isSelected _ TRUE; Labels.SetDisplayStyle[viewerToolData.textSection.selected, $WhiteOnBlack, TRUE]; SVEditUser.NewSelectedViewer[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]; }; -- Input Notify Procs SingleRay: PUBLIC PROC [viewerToolData: ViewerToolData, cameraPoint: Point2d] = TRUSTED { viewerPictureData: ViewerPictureData _ NARROW[viewerToolData.viewerPicture.data]; f: IO.STREAM _ SVEditUser.GetOutHandle[]; color: Color; xInt, yInt: INTEGER; tree: CSGTree; scene: Scene _ viewerPictureData.scene; camera: Camera _ viewerPictureData.camera; xInt _ Real.FixI[cameraPoint[1]]; yInt _ Real.FixI[cameraPoint[2]]; tree _ DisplayList3d.SceneToTree[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]; }; 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. viewerPictureData: ViewerPictureData _ NARROW[viewerToolData.viewerPicture.data]; f: IO.STREAM _ SVEditUser.GetOutHandle[]; tree: CSGTree; normal: Vector; prim: Primitive; scene: Scene _ viewerPictureData.scene; camera: Camera _ viewerPictureData.camera; class: CSG.Classification; tree _ DisplayList3d.SceneToTree[scene, camera]; class _ CastRays.SingleRay2[cameraPoint, tree, scene.lightSources, camera, TRUE, f]; IF class.count = 0 THEN RETURN; prim _ class.primitives[1]; normal _ class.normals[1]; }; 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]; viewerPictureData: ViewerPictureData _ NARROW[viewerToolData.viewerPicture.data]; camera: Camera _ viewerPictureData.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. Ęá˜JšĖĪc¸œĪk œžœTžœ|žœšžœžœžœžœˆžœąžœ!žœ žœ%žœ žœžœ+žœ-žœ(žœžœžœ&žœ(žœ&žœ'žœ+žœ%žœžœžœžœžœ#žœ!žœžœ*žœžœ'žœ5žœ5žœžœ-žœ9žœ!œ žœœ5žœžœžœžœAžœžœžœžœ*Īnœžœžœ žœžœžœžœ,žœžœ%žœ6žœRœVžœžœžœžœžœžœ.žœœžœžœžœ$œœšœ%žœœ_žœœ-1œqžœöžœ Ÿœžœžœ žœžœžœžœ,žœžœ%žœ6žœ“žœ!žœ=œVžœžœžœžœžœœžœžœžœžœžœ@œœÛžœūžœŸ œžœžœ žœžœžœžœ,žœžœ%žœ6žœCžœžœ!žœ=œVžœžœžœžœžœœžœžœžœžœžœ@œœãžœūžœ Ÿ œžœžœ žœžœžœžœ,žœžœ#œ"žœ6žœRŸ œžœžœmœŸ œžœžœ žœžœžœžœ,žœžœ#œ"žœ6žœgžœMžœ=Ÿœžœžœ–œŸœžœžœ žœžœžœžœ,žœžœ%žœHžœŋžœwžœŅžœžœ žœžœžœ&žœzœ0Ÿœžœžœ žœžœžœžœ,žœžœ?œ%Ÿœžœžœ žœžœžœžœ,žœžœ—žœ žœžœžœžœžœžœžœžœ žœžœžœžœžœžœžœ¯œžœ3žœ,žœXžœ1žœ/žœŠœ[žœžœžœ%žœ!žœžœžœ–:œWžœžœžœ Ÿœžœžœ žœžœžœžœ,žœžœ%žœ6žœR_œžœŸœžœžœ¨Ÿœžœžœ!žœžœžœ:žœžœ°žœwŸ œžœžœ žœžœžœžœ,žœžœ"œ"žœ6žœCžœUžœužœMžœ=Ÿ œžœžœųœŸœžœžœ žœžœžœžœ,žœžœ œ"žœ6žœCžœ,žœžžœMžœ=Ÿœžœžœ†žœ…œŸœžœžœ žœžœžœžœ,žœžœ%žœ6žœ–œŸ œžœžœ žœžœžœžœ,žœžœ%žœ6žœ|žœœVžœžœžœžœžœžœ.žœœBœœKžœžœžœģžœžœœŸœ%žœœbžœœ-1œ~žœđžœ Ÿ œžœžœžœžœžœžœžœ œŸ œžœžœ žœžœžœžœ,žœžœ%žœNŸ œžœžœ žœžœžœžœ,žœžœ%žœNŸœžœžœ žœžœžœžœ,žœžœ%žœVŸœžœžœ žœžœžœžœ,žœžœ%žœU-œŸ œžœžœ žœžœžœžœ,žœžœ%žœ6žœ‰žœ;žœžœ–žœ:žœi$œžœžœ4œŸ œžœžœ žœžœžœžœ,žœžœžœ,žœ6žœ&žœ žœ&žœXžœ#žœ\œŸœžœžœ žœžœžœžœ,žœžœžœ,žœ6žœ&žœ žœ&žœXžœ#žœ\œœŸ œžœžœ žœžœžœžœ,žœžœ%žœ$žœ2žœtžœ=žœžœˆ œŸœžœžœ žœžœžœžœ,žœžœMœ"žœ7žœNžœ8Ÿ œžœžœ$žœOœžœžœžœžœ+žœNžœ œŸ œžœžœ:žœ+žœ)žœžœ:žœŠžœpŸœžœžœ:žœĩœ(žœ)žœžœŽžœžœžœžœžœAŸœžœ!žœGœQœ"žœ6žœYžœ;ŸœžœžœŨžœ˜šÉ—…—dœmƒ