DIRECTORY CastRays, CoordSys, CSG, SVScene, Imager, Matrix3d, SV2d, SV3d, SVEditUser, SVError, SVInterfaceTypes, SVModelTypes, SVRayTypes, SVSceneTypes, SVSelections, SVStretch, SVTransforms, SVVector3d, SVViewerUser; SVStretchImpl: CEDAR PROGRAM IMPORTS CastRays, CoordSys, CSG, SVScene, 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; 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.", oneLiner]; 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.", oneLiner]; SVError.Blink[]; success _ FALSE; RETURN; }; SVScene.AddOrResizeToolToAssembly[planeAssem, scene]; }; 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: Imager.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.", oneLiner]; 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.", oneLiner]; 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: Imager.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.", oneLiner]; 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: Imager.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", oneLiner]; 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.", oneLiner]; 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 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: Imager.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.", oneLiner]; 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: Imager.Context] = TRUSTED { SVViewerUser.DrawAssemblyXOR[dc, viewerToolData, assembly]; }; DoRedrawSelection: PROC [dc: Imager.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: Imager.Context] = TRUSTED { SVViewerUser.DrawAssemblyXOR[dc, viewerToolData, assembly]; }; DoRedrawSelection: PROC [dc: Imager.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. XFile: SVStretchImpl.mesa Last edited by: Eric Bier on January 27, 1987 11:48:25 pm PST Copyright c 1984 by Xerox Corporation. All rights reserved. Contents: Interactive solidviews operations like dragging and stretching objects. Make sure the target has a working toolData. DoDrawCoordFrame: PROC [dc: Imager.Context] = TRUSTED { oldMode: Imager.PaintMode; oldMode _ Imager.SetPaintMode[dc, invert]; SVDraw3d.DrawCoordSys[dc, dragee.coordSys.wrtCamera, camera]; [] _ Imager.SetPaintMode[dc, oldMode]; }; Drag the source assembly. The origin of this assembly defines a plane parallel to the plane of the screen. We compute this plane. We cast a single ray at this plane and compute the current displacement between the assembly origin and this point. As we drag, we maintain this displacement. Find the origin of assembly in terms of camera. Compute the dragging plane. Cast a ray at the target plane. Returns result in CAMERA coordinates. Compute in CAMERA the displacement from hitPoint to origin. Draw a coordinate frame at the current spot (as a form of highlighting). Drag the source assembly. The origin of this assembly defines a plane parallel to the plane of target. We compute this plane. We cast a single ray at this plane and compute the current displacement between the assembly origin and this point. As we drag, we maintain this displacement. Find the origin of assembly in terms of target. Compute the dragging plane. Cast a ray at the target plane. Returns result in CAMERA coordinates. Compute in CAMERA the displacement from hitPoint to origin. Draw a coordinate frame at the current spot (as a form of highlighting). targetPlanePt is in CAMERA coords. Cast a ray at the dragging plane. Move the dragee so as to maintain the displacement between the dragee origin and the ray tracing point. Cast a ray at the dragging plane. Erase the old assembly coordsys, and body. Place the assembly's coordinate systems at this new point. Draw a coordinate frame and assembly at the new spot. Update the ray tracing tree for this node. To be implemented. Cast a ray at the dragging plane. newRay _ CSG.GetRayFromPool[]; CSG.StuffCameraRay[newRay, cameraPoint, camera]; [cameraWallPoint, parallel] _ CastRays.RayMeetsPlaneOfCoordSystem[newRay, camera.coordSys, 3, viewerToolData.dragPlaneDepth]; CSG.ReturnRayToPool[newRay]; newOriginPoint _ SVVector3d.Add[cameraWallPoint, viewerToolData.dragCameraVector]; IF parallel THEN ERROR; Cast a ray at the dragging plane. Move the dragee so as to maintain the displacement between the dragee origin and the ray tracing point. Cast a ray at the dragging plane. Erase the old assembly, coordsys and body. Place the assembly's coordinate systems at this new point. Draw a coordinate frame at the new spot. Update the ray tracing tree for this node. To be implemented. SVViewerUser.Painter[DoDrawAssembly, viewerToolData]; SVViewerUser.Painter[DoRedrawSelection, viewerToolData]; Redraw the scene and show that it has been edited. SVViewerUser.Painter[DoDrawAssembly, viewerToolData]; SVViewerUser.Painter[DoRedrawSelection, viewerToolData]; Redraw the scene and show that it has been edited. Κ ž˜Ihead™Jšœ=™=Jšœ Οmœ1™