<> <> <> 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.