DIRECTORY CastRays, CoordSys, CSG, DisplayList3d, Imager, 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; 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]; }; 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.", 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: 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.", 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: 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", 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 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.", 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: 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. LFile: SVStretchImpl.mesa Last edited by: Eric Bier on August 1, 1985 6:03:51 pm PDT Copyright c 1984 by Xerox Corporation. All rights reserved. Contents: Interactive solidviews operations like dragging and stretching objects. First cast a ray to grab hold of a primitive. viewerToolData.tree _ DisplayListToTree.AssemblyToTree[viewerToolData.scene.assembly, viewerToolData.scene, camera]; [] _ Preprocess3d.PreprocessForInteraction[viewerToolData.tree, camera]; class _ CastRays.SingleRay2[cameraPoint, viewerToolData.tree, camera]; [surfacePtInWorld, worldNormal] _ CastRays.FirstSurfacePointAndNormal[class, viewerToolData.camera, cameraPoint]; [assembly, primitive] _ CastRays.FirstAssemblyAndPrimitive[class]; IF success THEN { worldWRTCamera _ Matrix3d.Inverse[CoordSys.FindInTermsOfWorld[camera.coordSys]]; surfacePtInCamera _ Matrix3d.Update[worldWRTCamera, surfacePtInWorld]; viewerToolData.dragAssembly _ assembly; viewerToolData.dragPlaneDepth _ surfacePtInCamera[3]; SVTransforms.TellAboutParent[assembly.coordSys]; originInCamera _ Matrix3d.OriginOfMatrix[assembly.coordSys.wrtCamera]; viewerToolData.dragCameraVector _ SVVector3d.Sub[originInCamera, surfacePtInCamera]; SVViewerUser.Painter[DoDrawBoundBox, viewerToolData]; }; 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™J˜Jšœ žœ˜Jšžœ˜Jšœ˜—JšœŸ œ˜3J˜JšŸ œ%˜/JšœŸ œ˜'šžœžœžœ˜Jšœ2žœžœ˜>J˜Jšœ žœ˜Jšžœ˜J˜J™,—Jšœ;˜;J˜J˜—š œžœžœ™7Jšœ™Jšœ*™*Jšœ=™=Jšœ&™&Jšœ™—š œžœžœ:žœ˜_J™€Jšœ9˜9Jšœ'˜'Jšœ$˜$JšœΟuœ ‘œ ˜&J˜J˜Jšœžœ˜š œžœžœ˜7JšœB˜BJ˜—J˜Jšœ žœ˜Jšœ$˜$Jšžœ žœžœžœ˜JšŸ œ Ÿ ˜šžœ žœžœ˜Jšœžœ˜"Jšœ2žœžœ˜>J˜Jšœ žœ˜Jšžœ˜Jšœ˜—JšœŸ œ ˜%Jšžœžœ žœžœ˜˜J™/—šœ‘œ[˜gJ™—šœŸœ ‘œŸ˜1J™F—Jšœ ‘œŸœ5˜ešžœ žœ˜JšœFžœžœ˜RJšœ˜Jšœžœ˜ Jšžœ˜Jšœ˜J™;—šœŸœ‘œ ‘œ˜OJ™H—Jšœ7˜7Jšœ˜J˜—š  œžœžœ:žœ˜YJ™ Jšœ9˜9Jšœ'˜'Jšœ‘œ ‘œ‘œ ˜4Jšœžœ˜ J˜J˜Jšœžœ˜š œžœžœ˜7JšœB˜BJ˜—J˜JšœŸ œŸ œ*˜@Jšžœžœ žœžœ˜J˜˜J™/—Jšœ‘œ6˜Bšœ‘œ‘œ(˜WJ™—šœŸœ-‘œ˜SJ™F—Jšœ ‘œŸœH˜xšžœ žœ˜Jšœ@žœžœ˜LJšœ˜Jšœžœ˜ Jšžœ˜Jšœ˜J™;—šœŸœ‘œ ‘œ˜OJ™H—Jšœ7˜7JšœΟc˜J˜—š  œžœžœ'žœ žœ žœ˜iJ˜Jšœ žœ#˜4Jšžœžœ˜.Jšžœ"˜&Jšœ˜J˜J˜—š œžœžœ1žœ žœžœ ‘œžœžœ˜°Jšœ"™"Jšœ‘œ˜Jšœ‘œ ˜Jšœ‘œ ˜Jšœ‘œžœ˜ Jšžœ‘œ˜;Jšœ‘œF‘œ˜hJšœ‘œE˜PJšœ‘œ‘œ ‘œ˜;Jšžœ‘œ˜J˜J˜—š œžœžœžœžœ ‘œžœžœ˜’Jšœ‘œ˜Jšœ‘œ ˜Jšœ‘œ ˜Jšœ‘œžœ˜ Jšžœ‘œ˜;Jšœ‘œF‘œ ˜dJšœ‘œE˜PJšœ‘œ‘œ ‘œ˜;Jšžœ‘œ˜J˜J˜—š œžœžœ:žœ˜WJ™ŠJšœ'˜'Jšœ$˜$Jšœ‘œ˜(J˜J˜Jšœ žœ˜š œžœžœ˜5Jšœ  œŸœ˜9Jšœ˜—J˜JšŸœ˜%Jšžœ žœžœžœ˜JšŸœ˜#Jšžœ žœžœžœ˜JšŸœžœ#˜4šžœ žœžœ˜Jšœ0žœžœ˜žœžœ˜JJšœ˜Jšžœ˜Jšœ˜—J˜šŸœ‘œ#˜QJ™J™*—JšœŸœ˜5˜J™:—Jšœ4˜4Jšœr˜rJšœ.˜.˜J™5—JšœŸœ˜5˜J™*J™—Jšœ’˜J˜J™!Jšœ žœ™Jšžœ-™0Jšœ}™}Jšžœ™JšœR™RJšžœ žœžœ™J™—š  œžœžœ:žœ˜]J™ŠJšœ'˜'Jšœ$˜$Jšœ‘œ˜(J˜Jšœ žœ˜š œžœžœ˜5Jšœ1Ÿœ˜9Jšœ˜—J˜JšŸœ˜%Jšžœ žœžœžœ˜˜J™!—Jšœ ‘œV˜ešžœ žœ˜JšœDžœžœ˜PJšœ˜Jšžœ˜Jšœ˜—J˜JšŸœ‘œŸœ˜Q™J™*—JšœŸœ˜5˜J™:—Jšœ4˜4Jšœr˜rJšœ.˜.˜J™(—JšœŸœ˜5˜J™*J™—Jšœ˜J˜—š œžœžœ;˜O˜Jšœžœ˜AJšœ'˜'Jšœ$˜$J˜Jšœžœ˜9š œžœžœ˜5Jšœ  œ˜;Jšœ˜—š œžœžœ˜8JšœB˜BJ˜—J˜Jšœ žœ˜/Jšžœ žœžœžœ˜J˜$J˜JšŸœ˜%JšœŸœ™5šœ8™8J™2—Iprocšœ+˜+LšœX˜XJšœ˜—J˜—š  œžœžœ;˜U˜Jšœžœ˜AJšœ'˜'Jšœ$˜$J˜Jšœ˜š œžœžœ˜5Jšœ  œ˜;Jšœ˜—š œžœžœ˜8JšœB˜BJ˜—J˜Jšœ žœ˜/Jšžœ žœžœžœ˜J˜$J˜JšŸ œ˜+JšœŸœ™5šœ8™8J™2—Lšœ+˜+LšœX˜XJšœ˜—J˜—J˜Jšžœ˜J˜—…—&ΜCΓ