<> <> <> <> DIRECTORY CastRays, CoordSys, CSG, DisplayList3d, Graphics, Matrix3d, SV2d, SV3d, SVEditUser, SVError, SVInterfaceTypes, SVModelTypes, SVRayTypes, SVSceneTypes, SVSelections, SVStretch, SVTransforms, SVVector3d, SVViewerUser; SVStretchImpl: CEDAR PROGRAM IMPORTS CastRays, CoordSys, CSG, DisplayList3d, Matrix3d, SVEditUser, SVError, SVSelections, SVTransforms, SVVector3d, SVViewerUser EXPORTS SVStretch = BEGIN Assembly: TYPE = SVSceneTypes.Assembly; Camera: TYPE = SVModelTypes.Camera; Classification: TYPE = SVRayTypes.Classification; EditToolData: TYPE = SVEditUser.EditToolData; Matrix4by4: TYPE = SV3d.Matrix4by4; Point2d: TYPE = SV2d.Point2d; Point3d: TYPE = SV3d.Point3d; Primitive: TYPE = SVRayTypes.Primitive; Ray: TYPE = SVRayTypes.Ray; Scene: TYPE = SVSceneTypes.Scene; Selection: TYPE = SVInterfaceTypes.Selection; ToolData: TYPE = SVSceneTypes.ToolData; Vector: TYPE = SV3d.Vector; ViewerToolData: TYPE = SVInterfaceTypes.ViewerToolData; <> <> <<[] _ Preprocess3d.PreprocessForInteraction[viewerToolData.tree, camera];>> <> <<[surfacePtInWorld, worldNormal] _ CastRays.FirstSurfacePointAndNormal[class, viewerToolData.camera, cameraPoint];>> <<[assembly, primitive] _ CastRays.FirstAssemblyAndPrimitive[class];>> <> <> <> <> <> <> <> <> <> <<};>> <<>> StartDragAux: PRIVATE PROC [viewerToolData: ViewerToolData] RETURNS [drageeSel: Selection, planeAssem: Assembly, success: BOOL] = TRUSTED { scene: Scene _ viewerToolData.scene; success _ TRUE; drageeSel _ SVSelections.TopMovee[]; IF drageeSel = NIL THEN { viewerToolData.dragAssembly _ NIL; SVError.Append["Please select a source to drag.", TRUE, TRUE]; SVError.Blink[]; success _ FALSE; RETURN; }; viewerToolData.dragAssembly _ drageeSel.coincident; planeAssem _ SVSelections.TopPlaneCoincident[]; viewerToolData.dragTarget _ planeAssem; IF planeAssem = NIL THEN { SVError.Append["Please select a dragging plane.", TRUE, TRUE]; SVError.Blink[]; success _ FALSE; RETURN; }; <> DisplayList3d.AddOrResizeToolToAssembly[planeAssem, scene]; }; <> <> <> <> <<[] _ Graphics.SetPaintMode[dc, oldMode];>> <<};>> StartCameraDrag: PUBLIC PROC [viewerToolData: ViewerToolData, cameraPoint: Point2d] = TRUSTED { <> editToolData: EditToolData _ viewerToolData.editToolData; camera: Camera _ viewerToolData.camera; scene: Scene _ viewerToolData.scene; originCamera, hitPointCAMERA: Point3d; dragee: Assembly; drageeSel: Selection; parallel, success: BOOL; DoEraseSelection: PROC [dc: Graphics.Context] = TRUSTED { SVSelections.ComplementSelectionDC[dc, drageeSel, viewerToolData]; }; success _ TRUE; drageeSel _ SVSelections.TopMovee[]; IF drageeSel = NIL THEN RETURN; dragee _ drageeSel.coincident; IF dragee = NIL THEN { viewerToolData.dragAssembly _ NIL; SVError.Append["Please select a source to drag.", TRUE, TRUE]; SVError.Blink[]; success _ FALSE; RETURN; }; viewerToolData.dragAssembly _ dragee; IF NOT success THEN RETURN; <> originCamera _ Matrix3d.OriginOfMatrix[CoordSys.FindInTermsOfCamera[dragee.coordSys, camera.coordSys]]; <> viewerToolData.dragPlaneDepth _ originCamera[3]; <> [hitPointCAMERA, parallel] _ RayMeetsCameraPlane[cameraPoint, viewerToolData.dragPlaneDepth, camera]; IF parallel THEN { SVError.Append["StartCameraDrag: Dragging plane is parallel to ray.", TRUE, TRUE]; SVError.Blink[]; viewerToolData.dragTarget _ NIL; RETURN; }; <> viewerToolData.dragCameraVector _ SVVector3d.Sub[originCamera, hitPointCAMERA]; <> SVViewerUser.Painter[DoEraseSelection, viewerToolData]; }; StartDrag: PUBLIC PROC [viewerToolData: ViewerToolData, cameraPoint: Point2d] = TRUSTED { <> editToolData: EditToolData _ viewerToolData.editToolData; camera: Camera _ viewerToolData.camera; originCamera, hitPointCAMERA, originTarget: Point3d; plane: NAT; drageeSel: Selection; dragee, planeAssem: Assembly; parallel, success: BOOL; DoEraseSelection: PROC [dc: Graphics.Context] = TRUSTED { SVSelections.ComplementSelectionDC[dc, drageeSel, viewerToolData]; }; [drageeSel, planeAssem, success] _ StartDragAux[viewerToolData]; IF NOT success THEN RETURN; dragee _ drageeSel.coincident; <> originCamera _ Matrix3d.OriginOfMatrix[dragee.coordSys.wrtCamera]; originTarget _ CoordSys.FromCSToCS[originCamera, camera.coordSys, planeAssem.coordSys]; <> [viewerToolData.dragPlaneDepth, plane] _ DepthFromTarget[planeAssem, originTarget]; <> [hitPointCAMERA, parallel] _ RayMeetsTargetPlane[cameraPoint, planeAssem, viewerToolData.dragPlaneDepth, plane, camera]; IF parallel THEN { SVError.Append["StartDrag: Dragging plane is parallel to ray.", TRUE, TRUE]; SVError.Blink[]; viewerToolData.dragTarget _ NIL; RETURN; }; <> viewerToolData.dragCameraVector _ SVVector3d.Sub[originCamera, hitPointCAMERA]; <> SVViewerUser.Painter[DoEraseSelection, viewerToolData]; }; -- end of StartDrag DepthFromTarget: PRIVATE PROC [target: Assembly, targetPt: Point3d] RETURNS [depth: REAL, plane: NAT] = { toolData: ToolData; toolData _ NARROW[target.toolMasterObject.mainBody]; IF toolData.plane > 3 THEN depth _ targetPt[3] ELSE depth _ targetPt[toolData.plane]; plane _ toolData.plane; }; RayMeetsTargetPlane: PRIVATE PROC [cameraPoint: Point2d, planeA: Assembly, depth: REAL, plane: NAT, camera: Camera] RETURNS [planePtCamera: Point3d, parallel: BOOL] = TRUSTED { <> rayWorld: Ray; worldCamera: Matrix4by4; planePtWorld: Point3d; rayWorld _ CSG.GetRayFromPool[]; CSG.StuffWorldRayFromCamera[rayWorld, cameraPoint, camera]; [planePtWorld, parallel] _ CastRays.RayMeetsPlaneOfCoordSystem[planeA.coordSys, rayWorld, plane, depth]; worldCamera _ CoordSys.FindAInTermsOfB[camera.coordSys.parent, camera.coordSys]; planePtCamera _ Matrix3d.Update[worldCamera, planePtWorld]; CSG.ReturnRayToPool[rayWorld]; }; RayMeetsCameraPlane: PRIVATE PROC [cameraPoint: Point2d, depth: REAL, camera: Camera] RETURNS [planePtCamera: Point3d, parallel: BOOL] = TRUSTED { rayWorld: Ray; worldCamera: Matrix4by4; planePtWorld: Point3d; rayWorld _ CSG.GetRayFromPool[]; CSG.StuffWorldRayFromCamera[rayWorld, cameraPoint, camera]; [planePtWorld, parallel] _ CastRays.RayMeetsPlaneOfCoordSystem[camera.coordSys, rayWorld, 3, depth]; worldCamera _ CoordSys.FindAInTermsOfB[camera.coordSys.parent, camera.coordSys]; planePtCamera _ Matrix3d.Update[worldCamera, planePtWorld]; CSG.ReturnRayToPool[rayWorld]; }; SetDrag: PUBLIC PROC [viewerToolData: ViewerToolData, cameraPoint: Point2d] = TRUSTED { <> camera: Camera _ viewerToolData.camera; scene: Scene _ viewerToolData.scene; hitPointCAMERA, newOriginPoint: Point3d; dragee, target: Assembly; toolData: ToolData; parallel: BOOL; DoDrawAssembly: PROC [dc: Graphics.Context] = TRUSTED { SVViewerUser.DrawAssemblyXOR[dc, viewerToolData, dragee]; }; dragee _ viewerToolData.dragAssembly; IF dragee = NIL THEN RETURN; target _ viewerToolData.dragTarget; IF target = NIL THEN RETURN; toolData _ NARROW[target.toolMasterObject.mainBody]; IF toolData = NIL THEN { SVError.Append["Dragging plane is not defined", TRUE, TRUE]; SVError.Blink[]; RETURN; }; <> [hitPointCAMERA, parallel] _ RayMeetsTargetPlane[cameraPoint, viewerToolData.dragTarget, viewerToolData.dragPlaneDepth, toolData.plane, camera]; IF parallel THEN { SVError.Append["SetDrag: Dragging plane is parallel to ray.", TRUE, TRUE]; SVError.Blink[]; RETURN; }; newOriginPoint _ SVVector3d.Add[hitPointCAMERA, viewerToolData.dragCameraVector]; <<>> <> SVViewerUser.Painter[DoDrawAssembly, viewerToolData]; <> SVTransforms.Abut[dragee.coordSys, camera.coordSys]; SVTransforms.Translate[dragee.coordSys, camera.coordSys, newOriginPoint[1], newOriginPoint[2], newOriginPoint[3]]; SVTransforms.TellAboutParent[dragee.coordSys]; <> SVViewerUser.Painter[DoDrawAssembly, viewerToolData]; <> <> }; -- end of SetDrag <> <> <> <<[cameraWallPoint, parallel] _ CastRays.RayMeetsPlaneOfCoordSystem[newRay, camera.coordSys, 3, viewerToolData.dragPlaneDepth];>> <> <> <> <<>> SetCameraDrag: PUBLIC PROC [viewerToolData: ViewerToolData, cameraPoint: Point2d] = TRUSTED { <> camera: Camera _ viewerToolData.camera; scene: Scene _ viewerToolData.scene; hitPointCAMERA, newOriginPoint: Point3d; dragee: Assembly; parallel: BOOL; DoDrawAssembly: PROC [dc: Graphics.Context] = TRUSTED { SVViewerUser.DrawAssemblyXOR[dc, viewerToolData, dragee]; }; dragee _ viewerToolData.dragAssembly; IF dragee = NIL THEN RETURN; <> [hitPointCAMERA, parallel] _ RayMeetsCameraPlane[cameraPoint, viewerToolData.dragPlaneDepth, camera]; IF parallel THEN { SVError.Append["SetCameraDrag: Dragging plane is parallel to ray.", TRUE, TRUE]; SVError.Blink[]; RETURN; }; newOriginPoint _ SVVector3d.Add[hitPointCAMERA, viewerToolData.dragCameraVector]; <<>> <> SVViewerUser.Painter[DoDrawAssembly, viewerToolData]; <> SVTransforms.Abut[dragee.coordSys, camera.coordSys]; SVTransforms.Translate[dragee.coordSys, camera.coordSys, newOriginPoint[1], newOriginPoint[2], newOriginPoint[3]]; SVTransforms.TellAboutParent[dragee.coordSys]; <> SVViewerUser.Painter[DoDrawAssembly, viewerToolData]; <> <> }; EndDrag: PUBLIC PROC [viewerToolData: ViewerToolData, cameraPoint: Point2d] = { editToolData: EditToolData _ NARROW[viewerToolData.editToolData]; camera: Camera _ viewerToolData.camera; scene: Scene _ viewerToolData.scene; drageeSel: Selection; assembly: Assembly _ NARROW[viewerToolData.dragAssembly]; DoDrawAssembly: PROC [dc: Graphics.Context] = TRUSTED { SVViewerUser.DrawAssemblyXOR[dc, viewerToolData, assembly]; }; DoRedrawSelection: PROC [dc: Graphics.Context] = TRUSTED { SVSelections.ComplementSelectionDC[dc, drageeSel, viewerToolData]; }; assembly _ NARROW[viewerToolData.dragAssembly]; IF assembly = NIL THEN RETURN; drageeSel _ SVSelections.TopMovee[]; SetDrag[viewerToolData, cameraPoint]; <> <> <> SVEditUser.SceneNewVersion[viewerToolData]; SVEditUser.PaintSceneAllViewers[SVViewerUser.EraseAndDrawSceneEtc, editToolData, scene]; }; EndCameraDrag: PUBLIC PROC [viewerToolData: ViewerToolData, cameraPoint: Point2d] = { editToolData: EditToolData _ NARROW[viewerToolData.editToolData]; camera: Camera _ viewerToolData.camera; scene: Scene _ viewerToolData.scene; drageeSel: Selection; assembly: Assembly; DoDrawAssembly: PROC [dc: Graphics.Context] = TRUSTED { SVViewerUser.DrawAssemblyXOR[dc, viewerToolData, assembly]; }; DoRedrawSelection: PROC [dc: Graphics.Context] = TRUSTED { SVSelections.ComplementSelectionDC[dc, drageeSel, viewerToolData]; }; assembly _ NARROW[viewerToolData.dragAssembly]; IF assembly = NIL THEN RETURN; drageeSel _ SVSelections.TopMovee[]; SetCameraDrag[viewerToolData, cameraPoint]; <> <> <> SVEditUser.SceneNewVersion[viewerToolData]; SVEditUser.PaintSceneAllViewers[SVViewerUser.EraseAndDrawSceneEtc, editToolData, scene]; }; END.