DIRECTORY CastRays, CoordSys, CSG, CSGGraphics, DisplayList3d, Graphics, GraphicsColor, Matrix3d, Preprocess3d, SV2d, SVBoundBox, SVEditUser, SVInputMonitor, SVVector3d, SVViewerInput, SVViewerUser, TIPUser, ViewerClasses; SVViewerInputImpl: PROGRAM IMPORTS CastRays, CoordSys, CSGGraphics, DisplayList3d, Graphics, Matrix3d, Preprocess3d, SVBoundBox, SVEditUser, SVInputMonitor, SVViewerUser, SVVector3d EXPORTS SVViewerInput = BEGIN Assembly: TYPE = DisplayList3d.Assembly; BoundBox: TYPE = SVBoundBox.BoundBox; Camera: TYPE = CSGGraphics.Camera; Classification: TYPE = CSG.Classification; Color: TYPE = GraphicsColor.Color; CoordSystem: TYPE = CoordSys.CoordSystem; FileCamera: TYPE = DisplayList3d.FileCamera; FrameBox: TYPE = CSGGraphics.FrameBox; Matrix4by4: TYPE = Matrix3d.Matrix4by4; Point2d: TYPE = SV2d.Point2d; Point3d: TYPE = Matrix3d.Point3d; Primitive: TYPE = CSG.Primitive; Selection: TYPE = SVEditUser.Selection; Vector: TYPE = SVVector3d.Vector; ViewerToolData: TYPE = SVViewerUser.ViewerToolData; ViewerPictureData: TYPE = SVViewerUser.ViewerPictureData; InputNotify: PUBLIC SAFE PROCEDURE [self: ViewerClasses.Viewer, input: LIST OF REF ANY] = TRUSTED { IF ISTYPE[input.first, TIPUser.TIPScreenCoords] THEN { controlPoint: Point2d; viewerPictureData: ViewerPictureData _ NARROW[self.data]; viewerToolData: ViewerToolData _ viewerPictureData.viewerToolData; camera: Camera _ viewerPictureData.camera; mousePlace: TIPUser.TIPScreenCoords _ NARROW[input.first]; controlPoint[1] _ mousePlace.mouseX; -- this is a fix to float conversion controlPoint[2] _ mousePlace.mouseY; controlPoint _ CoordSys.ScreenToCamera[controlPoint, camera.screenCS]; IF ISTYPE[input.rest.first, ATOM] THEN SELECT input.rest.first FROM $SingleRay => { SVViewerUser.SingleRay[viewerToolData, controlPoint]; }; $FrameUpLeft => PositionUpLeft[viewerToolData, controlPoint]; $FrameDownRightMove => { }; $FrameDownRightEnd => { PositionDownRight[viewerToolData, controlPoint]; }; $DeleteFrame => DeleteFrame[viewerToolData]; $StartPrimarySelection => StartPrimarySelection[viewerToolData, controlPoint]; $StartSecondarySelection => StartSecondarySelection[viewerToolData, controlPoint]; $SetPrimarySelection => SVInputMonitor.NewMotion[controlPoint, NARROW[input.rest.first], viewerToolData]; $EndPrimarySelection => {}; $SetSecondarySelection => SVInputMonitor.NewMotion[controlPoint, NARROW[input.rest.first], viewerToolData]; $EndSecondarySelection => EndSecondarySelection[viewerToolData, controlPoint]; ENDCASE; }; -- is a Mousepoint }; -- end of InputNotify MakeAlignedMat: PRIVATE PROC [worldNormal: Vector, surfacePtInWorld: Point3d, cs: CoordSystem] RETURNS [mat: Matrix4by4] = TRUSTED { yAxisOfCS: Vector _ Matrix3d.YAxisOfMatrix[cs.wrtWorld]; xAxis: Vector; IF SVVector3d.Parallel[yAxisOfCS, worldNormal] THEN xAxis _ Matrix3d.XAxisOfMatrix[cs.wrtWorld] ELSE xAxis _ SVVector3d.CrossProduct[yAxisOfCS, worldNormal]; mat _ Matrix3d.MakeMatFromZandXAxis[worldNormal, xAxis, surfacePtInWorld]; }; StartPrimarySelection: PUBLIC PROC [viewerToolData: ViewerToolData, cameraPoint: Point2d] = TRUSTED { selectionMat: Matrix4by4; surfacePtInWorld: Point3d; worldNormal: Vector; assembly: Assembly; primitive: Primitive; class: Classification; selection, oldSelection: Selection; viewerPictureData: ViewerPictureData _ NARROW[viewerToolData.viewerPicture.data]; viewerPictureData.tree _ DisplayList3d.SceneToTree[viewerPictureData.scene, viewerPictureData.camera]; [] _ Preprocess3d.Preprocess[viewerPictureData.tree, viewerPictureData.camera]; class _ CastRays.SingleRay2[cameraPoint, viewerPictureData.tree, viewerPictureData.scene.lightSources, viewerPictureData.camera]; [surfacePtInWorld, worldNormal] _ DisectClassification1[class, viewerPictureData.camera, cameraPoint]; [assembly, primitive] _ DisectClassification2[class, viewerPictureData.camera, cameraPoint]; IF assembly # NIL THEN { selectionMat _ MakeAlignedMat[worldNormal, surfacePtInWorld, assembly.coordSys]; oldSelection _ SVEditUser.GetPrimarySelection[]; ComplementOldSelection[viewerToolData, oldSelection, GraphicsColor.black]; selection _ SVEditUser.SetPrimarySelection[cameraPoint, assembly, primitive, selectionMat, viewerToolData]; ComplementSelection[viewerToolData, selection, GraphicsColor.black]; -- draw new selection into complement mode }; CastRays.ReturnClassToPool[class]; }; ComplementOldSelection: PROC [viewerToolData: ViewerToolData, selection: Selection, color: Color] = TRUSTED { IF selection = NIL THEN RETURN; -- null selection IF selection.assembly = NIL THEN RETURN; -- null selection IF selection.viewerToolData = viewerToolData THEN ComplementSelection[viewerToolData, selection, color] ELSE ComplementSelection[selection.viewerToolData, selection, color]; }; DrawSelectionOpaque: PROC [viewerToolData: ViewerToolData, selection: Selection, color: Color] = TRUSTED { DoDrawSelectionOpaque: SAFE PROC [dc: Graphics.Context] = TRUSTED { [] _ Graphics.SetPaintMode[dc, opaque]; Graphics.SetColor[dc, color]; SVViewerUser.DrawOneCS[dc, viewerToolData, selection.coordSys]; }; CoordSys.TellAboutParent[selection.coordSys]; SVViewerUser.Painter[DoDrawSelectionOpaque, viewerToolData]; }; ComplementSelection: PROC [viewerToolData: ViewerToolData, selection: Selection, color: Color] = TRUSTED { DoComplementSelection: SAFE PROC [dc: Graphics.Context] = TRUSTED { [] _ Graphics.SetPaintMode[dc, invert]; Graphics.SetColor[dc, color]; SVViewerUser.DrawOneCS[dc, viewerToolData, selection.coordSys]; }; CoordSys.TellAboutParent[selection.coordSys]; SVViewerUser.Painter[DoComplementSelection, viewerToolData]; }; SetPrimarySelection: PUBLIC PROC [viewerToolData: ViewerToolData, cameraPoint: Point2d] = TRUSTED { selection: Selection; surfacePtInWorld: Point3d; worldNormal: Vector; assembly: Assembly; primitive: Primitive; selectionMat: Matrix4by4; viewerPictureData: ViewerPictureData _ NARROW[viewerToolData.viewerPicture.data]; class: Classification _ CastRays.SingleRay2[cameraPoint, viewerPictureData.tree, viewerPictureData.scene.lightSources, viewerPictureData.camera]; [surfacePtInWorld, worldNormal] _ DisectClassification1[class, viewerPictureData.camera, cameraPoint]; [assembly, primitive] _ DisectClassification2[class, viewerPictureData.camera, cameraPoint]; IF assembly # NIL THEN { selectionMat _ MakeAlignedMat[worldNormal, surfacePtInWorld, assembly.coordSys]; selection _ SVEditUser.GetPrimarySelection[]; ComplementSelection[viewerToolData, selection, GraphicsColor.black];-- erase old one by complementing selection _ SVEditUser.SetPrimarySelection[cameraPoint, assembly, primitive, selectionMat, viewerToolData]; ComplementSelection[viewerToolData, selection, GraphicsColor.black];-- paint new one by complementing }; CastRays.ReturnClassToPool[class]; }; DisectClassification1: PROC [class: Classification, camera: Camera, cameraPoint: Point2d] RETURNS [surfacePtInWorld: Point3d, worldNormal: Vector] = TRUSTED { worldBasePt: Point3d; primitive: Primitive; primitiveNormal, worldDirection: Vector; t: REAL; IF class.count = 0 THEN RETURN; t _ class.params[1];-- the parameter of the ray intersection primitiveNormal _ class.normals[1]; primitive _ class.primitives[1]; worldNormal _ Matrix3d.UpdateVectorWithInverse[primitive.worldWRTPrim, primitiveNormal]; worldBasePt _ Matrix3d.Update[camera.coordSys.mat, [cameraPoint[1], cameraPoint[2], 0]]; worldDirection _ Matrix3d.UpdateVectorEvenScaling[camera.coordSys.mat, [cameraPoint[1], cameraPoint[2], -camera.focalLength]]; surfacePtInWorld[1] _ worldBasePt[1] + t*worldDirection[1]; surfacePtInWorld[2] _ worldBasePt[2] + t*worldDirection[2]; surfacePtInWorld[3] _ worldBasePt[3] + t*worldDirection[3]; }; -- end of DisectClassification1 DisectClassification2: PROC [class: Classification, camera: Camera, cameraPoint: Point2d] RETURNS [assembly: Assembly, primitive: Primitive] = TRUSTED { IF class.count = 0 THEN RETURN[NIL, NIL]; primitive _ class.primitives[1]; assembly _ NARROW[primitive.assembly]; }; -- end of DisectClassification2 StartSecondarySelection: PUBLIC PROC [viewerToolData: ViewerToolData, cameraPoint: Point2d] = TRUSTED { selectionMat: Matrix4by4; surfacePtInWorld: Point3d; worldNormal: Vector; assembly: Assembly; primitive: Primitive; class: Classification; selection, oldSelection: Selection; viewerPictureData: ViewerPictureData _ NARROW[viewerToolData.viewerPicture.data]; viewerPictureData.tree _ DisplayList3d.SceneToTree[viewerPictureData.scene, viewerPictureData.camera]; [] _ Preprocess3d.Preprocess[viewerPictureData.tree, viewerPictureData.camera]; class _ CastRays.SingleRay2[cameraPoint, viewerPictureData.tree, viewerPictureData.scene.lightSources, viewerPictureData.camera]; [surfacePtInWorld, worldNormal] _ DisectClassification1[class, viewerPictureData.camera, cameraPoint]; [assembly, primitive] _ DisectClassification2[class, viewerPictureData.camera, cameraPoint]; IF assembly # NIL THEN { selectionMat _ MakeAlignedMat[worldNormal, surfacePtInWorld, assembly.coordSys]; oldSelection _ SVEditUser.GetSecondarySelection[]; ComplementOldSelection[viewerToolData, oldSelection, GraphicsColor.black]; selection _ SVEditUser.SetSecondarySelection[cameraPoint, assembly, primitive, selectionMat, viewerToolData]; ComplementSelection[viewerToolData, selection, GraphicsColor.black]; -- draw new selection into complement mode }; CastRays.ReturnClassToPool[class]; }; SetSecondarySelection: PUBLIC PROC [viewerToolData: ViewerToolData, cameraPoint: Point2d] = TRUSTED { selection: Selection; surfacePtInWorld: Point3d; worldNormal: Vector; assembly: Assembly; primitive: Primitive; selectionMat: Matrix4by4; viewerPictureData: ViewerPictureData _ NARROW[viewerToolData.viewerPicture.data]; class: Classification _ CastRays.SingleRay2[cameraPoint, viewerPictureData.tree, viewerPictureData.scene.lightSources, viewerPictureData.camera]; [surfacePtInWorld, worldNormal] _ DisectClassification1[class, viewerPictureData.camera, cameraPoint]; [assembly, primitive] _ DisectClassification2[class, viewerPictureData.camera, cameraPoint]; IF assembly#NIL THEN { selectionMat _ MakeAlignedMat[worldNormal, surfacePtInWorld, assembly.coordSys]; selection _ SVEditUser.GetSecondarySelection[]; ComplementSelection[viewerToolData, selection, GraphicsColor.black];-- erase old one by complementing selection _ SVEditUser.SetSecondarySelection[cameraPoint, assembly, primitive, selectionMat, viewerToolData]; ComplementSelection[viewerToolData, selection, GraphicsColor.black];-- paint new one by complementing }; CastRays.ReturnClassToPool[class]; }; EndSecondarySelection: PUBLIC PROC [viewerToolData: ViewerToolData, controlPoint: Point2d] = TRUSTED { oldSelection, secondarySelection: Selection; oldSelection _ SVEditUser.GetFinalSecondary[]; SetSecondarySelection[viewerToolData, controlPoint];-- set the selection to the final point secondarySelection _ SVEditUser.GetSecondarySelection[]; [] _ SVEditUser.SetFinalSecondary[secondarySelection.cameraPoint, secondarySelection.assembly, secondarySelection.primitive, secondarySelection.coordSys.wrtWorld, secondarySelection.viewerToolData]; IF oldSelection # NIL THEN { IF oldSelection.viewerToolData = viewerToolData AND oldSelection.assembly # NIL THEN ComplementBoundBox[oldSelection.primitive.boundBox, viewerToolData]; }; IF secondarySelection.assembly # NIL THEN ComplementBoundBox[secondarySelection.primitive.boundBox, viewerToolData]; }; ComplementBoundBox: PUBLIC PROC [boundBox: BoundBox, viewerToolData: ViewerToolData] = TRUSTED { viewerPictureData: ViewerPictureData _ NARROW[viewerToolData.viewerPicture.data]; camera: Camera _ viewerPictureData.camera; screen: CoordSystem _ camera.screenCS; DoComplementBoundBox: SAFE PROC [dc: Graphics.Context] = TRUSTED { SVBoundBox.ComplementBoundBox[dc, boundBox, screen]; }; SVViewerUser.Painter[DoComplementBoundBox, viewerToolData]; }; PositionUpLeft: PUBLIC PROC [viewerToolData: ViewerToolData, controlPoint: Point2d] = TRUSTED { viewerPictureData: ViewerPictureData _ NARROW[viewerToolData.viewerPicture.data]; camera: Camera _ viewerPictureData.camera; frame: FrameBox _ camera.frame; frame.fullScreen _ FALSE; frame.downLeft[1] _ controlPoint[1]; frame.upRight[2] _ controlPoint[2]; }; PositionDownRight: PUBLIC PROC [viewerToolData: ViewerToolData, controlPoint: Point2d] = TRUSTED { viewerPictureData: ViewerPictureData _ NARROW[viewerToolData.viewerPicture.data]; camera: Camera _ viewerPictureData.camera; frame: FrameBox _ camera.frame; fileCamera: FileCamera; success: BOOL; frame.downLeft[2] _ controlPoint[2]; frame.upRight[1] _ controlPoint[1]; DrawCameraFrame[viewerToolData]; [fileCamera, success] _ DisplayList3d.FindFileCameraFromName[camera.viewName, viewerPictureData.scene]; IF success THEN { fileCamera.frame.downLeft _ frame.downLeft; fileCamera.frame.upRight _ frame.upRight; fileCamera.frame.fullScreen _ FALSE; }; }; DeleteFrame: PROC [viewerToolData: ViewerToolData] = TRUSTED { viewerPictureData: ViewerPictureData _ NARROW[viewerToolData.viewerPicture.data]; camera: Camera _ viewerPictureData.camera; frame: FrameBox _ camera.frame; frame.fullScreen _ TRUE; }; DrawCameraFrame: PROC [viewerToolData: ViewerToolData] = TRUSTED { viewerPictureData: ViewerPictureData _ NARROW[viewerToolData.viewerPicture.data]; camera: Camera _ viewerPictureData.camera; DoDrawFrame: SAFE PROC [dc: Graphics.Context] = TRUSTED { Graphics.SetColor[dc, GraphicsColor.black]; CSGGraphics.DrawFrame [dc, camera]; }; SVViewerUser.Painter[DoDrawFrame, viewerToolData]; }; END. ÚFile: SVViewerInputImpl.mesa Last edited by Bier on August 11, 1983 11:09 am Contents: Procedures for responding to button clicks made in a solidviewer. Self is a viewer picture. Convert to camera coordinates. PositionDownRight[viewerToolData, controlPoint]; Create a Matrix4by4 with origin at surfacePtInWorld whose z axis is parallel to worldNormal and whose x zxis is orthogonal to both worldNormal and the y axis of cs in WORLD coordinates. Assume that cs.wrtWorld is accurate Compute the ray tracing tree for the current scene here so we don't have to recompute it each time the mouse position is sampled (SetPrimarySelection). If selection is in this viewer then just complement it normally. If it is in another viewer, then have that viewer complement it. If there it is a null selection, forget it. Cast a ray into the scene from this point. If it hits anything, use the surface normal at that point to derive a coordinate system whose z axis is the parallel to the normal. Tell the editTool that a new selection has been made. There are two Disect Classifications because Cedar can't handle a return record which both contains a pointer (assembly) and returns 6 REALS (long pointer-containing return record is unsafe) express the ray which was cast in world coordinates Use this ray to find the surface point in WORLD coordinates. This will be the origin of our coordinate system. Compute the ray tracing tree for the current scene here so we don't have to recompute it each time the mouse position is sampled (SetSecondarySelection). Cast a ray into the scene from this point. If it hits anything, use the surface normal at that point to derive a coordinate system whose z axis is the parallel to the normal. Tell the editTool that a new selection has been made. fake a button press to draw scene Is there an old selection in this viewer to complement? Controlpoint is in camera coordinates. Controlpoint is in camera coordinates. Tell the appropriate file camera about the new frame. Ê \˜Iheadšœ™Jšœ/™/JšœK™KJ˜šÏk ˜ Jšœ ˜ Jšœ ˜ Jšœ˜Jšœ ˜ Jšœ˜Jšœ ˜ Jšœ˜Jšœ ˜ Jšœ ˜ Jšœ˜Jšœ ˜ Jšœ ˜ Jšœ˜Jšœ ˜ Jšœ˜Jšœ ˜ Jšœ˜Jšœ˜—J˜šœ˜Jšœ“˜šJšœ˜—J˜š˜Jšœ œ˜(Jšœ œ˜%Jšœœ˜"Jšœœœ˜*Jšœœ˜"Jšœ œ˜)Jšœ œ˜,Jšœ œ˜&Jšœ œ˜'Jšœ œ˜Jšœ œ˜!Jšœ œœ ˜ Jšœ œ˜'Jšœœ˜!Jšœœ˜3Jšœœ"˜9J˜šÏn œœœ%œœœœœ˜cJšœ™šœœ'œ˜6Jšœ˜Jšœ'œ ˜9JšœB˜BJšœ*˜*Jšœ&œ˜:JšœI˜IJšœ$˜$JšœF˜FJšœ™Jšœœœ˜&šœ˜šœ˜Jšœ5˜5Jšœ˜—Jšœ=˜=šœ˜Jšœ0™0Jšœ˜—šœ˜Jšœ0˜0Jšœ˜—Jšœ,˜,JšœN˜NJšœR˜RJšœ?œ$˜iJšœ˜JšœAœ$˜kJšœN˜NJšœ˜—Jšœ˜—Jšœ˜—Jšœ˜š žœœœCœœ˜„JšœÞ™ÞJšœ8˜8Jšœ˜Jšœ-œ,˜_Jšœ9˜=JšœJ˜JJšœ˜—Jšœ˜šžœœœ:œ˜eJšœ—™—Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ#˜#Jšœ'œ$˜QJšœf˜fJšœO˜OJšœ˜Jšœf˜fJšœ\˜\šœ œœ˜JšœP˜PJšœ0˜0JšœJ˜JJšœk˜kJšœo˜oJšœ˜—Jšœ"˜"Jšœ˜—Jšœ˜šžœœHœ˜mJšœ¯™¯Jšœ œœœ˜1Jšœœœœ˜:Jšœ*˜,Jšœ6˜:JšœA˜EJšœ˜—Jšœ˜Jšœ˜šžœœHœ˜jšžœ œœ˜CJšœ'˜'Jšœ˜Jšœ?˜?Jšœ˜—Jšœ-˜-Jšœ<˜Jšœ'œ$˜QJšœ*˜*Jšœ˜Jšœœ˜Jšœ˜—Jšœ˜šžœœ$œ˜BJšœ'œ$˜QJšœ*˜*šž œ œœ˜9Jšœ+˜+Jšœ#˜#Jšœ˜—Jšœ2˜2Jšœ˜——Jšœ˜Jšœ˜Jšœ˜J˜—…—4ÒH