DIRECTORY Args, Commander, Controls, Controls3d, Draw2d, Draw3d, FS, IO, Matrix3d, Misc3d, Plane3d, Real, Rope, Spline3d, TubeDefs, TubeDisplay, TubeIO, TubeContour, TubeGeometry, TubeMisc, TubePick, Vector3d, ViewerOps; TubeTestsImpl: CEDAR PROGRAM IMPORTS Args, Commander, Controls, Controls3d, Draw2d, Draw3d, FS, IO, Matrix3d, Misc3d, Plane3d, Real, Rope, Spline3d, TubeDisplay, TubeIO, TubeContour, TubeGeometry, TubeMisc, TubePick, Vector3d, ViewerOps ~ BEGIN OPEN TubeDefs; UserData: TYPE ~ RECORD [o: OuterData, p: ProgramData]; ProgramData: TYPE ~ REF ProgramDataRep; ProgramDataRep: TYPE ~ RECORD [ cam: Camera _ NIL, -- camera controls space: Control _ NIL, -- space between objects spin: Control _ NIL, -- rotate about object's vertical axis tilt: Control _ NIL, -- rotate about object's horizontal axis size: Control _ NIL, -- size of object diameter: Control _ NIL, -- diameter of object circleRes: Control _ NIL, -- circle resolution epsilon: Control _ NIL, -- spline flatness threshold outer: Viewer _ NIL, graphics: Viewer _ NIL, view: Matrix _ NIL, scratchMatrix: Matrix _ NIL, tube: Tube _ NIL, tube1: Tube _ NIL, tube2: Tube _ NIL, web: Coeffs _ NIL, details: Details ]; TubeWeb: Commander.CommandProc ~ { p: ProgramData _ NEW[ProgramDataRep]; p.cam _ Controls3d.InitCamera[data: p, proc: CameraControl]; p.outer _ Controls.OuterViewer[ name: "Tube Web", controls: LIST[ p.cam.xGlobal, p.cam.yGlobal, p.cam.zGlobal, p.cam.scale, p.cam.hScreen, p.cam.vScreen], graphicsHeight: 300, graphicsShow: TubeWebShow, buttons: LIST[["Get Tube", GetTube]], data: p]; p.graphics _ NARROW[p.outer.data, OuterData].graphics; }; CameraControl: Controls3d.CameraProc ~ { p: ProgramData ~ NARROW[data]; ViewerOps.PaintViewer[p.graphics, client, FALSE, NIL]; }; TubeWebShow: Controls.GraphicsShow ~ { p: ProgramData _ NARROW[data]; Action: PROC ~ { p.view _ Controls3d.InitContext[context, p.cam, p.view]; TubeDisplay.DrawSplines[p.tube, context, p.view]; Draw3d.Curve[context, p.web, p.view]; Draw3d.Segment[context, p.tube1.p1, p.tube2.p1, p.view, dotted]; IF p.tube1 # NIL AND p.tube2 # NIL THEN FOR t: REAL _ 0.0, t+0.05 WHILE t <= 1.01 DO plane: Plane3d.Quad ~ Plane3d.FromPtNrm[ Spline3d.Position[p.web, t], Spline3d.Velocity[p.web, t]]; i1: Misc3d.PlaneIntersection _ Misc3d.IntersectSplineWithPlane[p.tube1.coeffs, plane]; i2: Misc3d.PlaneIntersection _ Misc3d.IntersectSplineWithPlane[p.tube2.coeffs, plane]; IF i1.nRoots = 1 AND i2.nRoots = 1 THEN { p1: Triple ~ Spline3d.Position[p.tube1.coeffs, i1.roots[0]]; p2: Triple ~ Spline3d.Position[p.tube2.coeffs, i2.roots[0]]; Draw3d.Segment[context, p1, p2, p.view] }; ENDLOOP; }; IF p.tube # NIL AND p.tube1 # NIL AND p.tube2 # NIL AND p.web # NIL THEN Draw2d.DoWithBuffer[context, Action]; }; GetTube: ClickProc ~ { p: ProgramData ~ NARROW[NARROW[clientData, OuterData].data]; p.tube _ TubeMisc.Copy[TubePick.LastTubePicked[]]; IF p.tube # NIL AND p.tube.branches # NIL AND p.tube.branches.length > 0 THEN { mid, ave, cross, tan: Triple; p.tube1 _ p.tube.next; p.tube2 _ p.tube.branches[0]; mid _ Vector3d.Mul[Vector3d.Add[p.tube1.p1, p.tube2.p1], 0.5]; ave _ Vector3d.Normalize[Vector3d.Add[p.tube1.v1, p.tube2.v1]]; cross _ Vector3d.Normalize[Vector3d.Sub[p.tube2.p1, mid]]; tan _ Vector3d.V90[cross, ave]; p.web _ Spline3d.CoeffsFromHermite[[p.tube1.p0, mid, p.tube1.v0, tan]]; }; ViewerOps.PaintViewer[p.graphics, client, FALSE, NIL]; }; TubeCompare: Commander.CommandProc ~ { arg: ROPE _ Args.GetRope[cmd]; p: ProgramData _ NEW[ProgramDataRep]; p.details _ NEW[DetailsRep]; p.cam _ Controls3d.InitCamera[data: p]; p.space _ Controls.NewControl["space", vSlider, p, 0.0, 2.5, 1.0, TubeControl]; p.spin _ Controls.NewControl["spin", dial, p, 0.0, 360.0, 0.0, TubeControl]; p.tilt _ Controls.NewControl["tilt", dial, p, 0.0, 360.0, 0.0, TubeControl]; p.size _ Controls.NewControl["size", vSlider, p, 0.0, 4.0, 1.75, TubeControl]; p.diameter _ Controls.NewControl["dia", vSlider, p, 0.001, 2.5, 1.2, TubeControl]; p.circleRes _ Controls.NewControl["cres", vSlider, p, 3.0, 20.0, 6.0, TubeControl,, TRUE]; p.epsilon _ Controls.NewControl["eps", vSlider, p, 0.01, 0.1, 0.03, TubeControl]; Controls.ControlRow[p.spin, 1]; IF arg # NIL THEN { stream: STREAM _ FS.StreamOpen[arg ! FS.Error => GOTO noOpen]; NewTubes[p, TubeIO.ReadTube[stream]]; IO.Close[stream]; EXITS noOpen => RETURN[$Error, Rope.Concat["Couldn't open ", arg]]; }; p.scratchMatrix _ NEW[MatrixRep]; p.outer _ Controls.OuterViewer[ name: "Tube Compare", controls: LIST[ p.cam.yGlobal, p.cam.zGlobal, p.cam.scale, p.cam.x, p.cam.y, p.cam.z, p.cam.fieldOfView, p.space, p.spin, p.tilt, p.size, p.diameter, p.circleRes, p.epsilon], graphicsHeight: 300, graphicsShow: TubesShow, buttons: LIST[ ["Tube-in", TubeIn], ["Label-On", TogLabel], ["Skel-Off", TogSkel], ["Splines-On", TogSpline], ["Circles-Off", TogContours], ["Lines-Off", TogLines], ["Frames-Off", TogFrames], ["Normals-Off", TogNormals]], typeScriptHeight: 18, data: p]; }; TubesShow: Controls.GraphicsShow ~ { p: ProgramData _ NARROW[data]; OffsetTubeDisplay: PROC [tube: Tube, dx: REAL] ~ { m: Matrix _ p.scratchMatrix; IF tube = NIL THEN RETURN; m _ Matrix3d.LocalTranslate[p.cam.matrix, [dx, 0.0, 0.0], m]; m _ Matrix3d.LocalScale[m, p.size.value]; m _ Matrix3d.LocalRotate[m, yAxis, p.spin.value, , , m]; m _ Matrix3d.LocalRotate[m, zAxis, p.tilt.value, , , m]; m _ Controls3d.TransformByViewPort[m, context, m]; TubeDisplay.DrawTube[tube, context, p.details, m] }; Action: PROC ~ { Draw2d.Clear[context]; OffsetTubeDisplay[p.tube1, -p.space.value]; OffsetTubeDisplay[p.tube1, p.space.value]; }; Draw2d.DoWithBuffer[context, Action]; }; TubeControl: Controls.ControlProc ~ { p: ProgramData _ NARROW[control.data]; IF control.mouse.state = up THEN RETURN; SELECT control FROM p.epsilon => NewTubes[p, p.tube1]; p.diameter => { TubeGeometry.ReScale[p.tube1, p.diameter.value]; TubeGeometry.ReScale[p.tube2, p.diameter.value]; }; p.circleRes => { TubeContour.PropagateCircleRes[p.tube1, Real.RoundI[p.circleRes.value]]; TubeContour.PropagateCircleRes[p.tube2, Real.RoundI[p.circleRes.value]]; }; ENDCASE => NULL; ViewerOps.PaintViewer[control.graphics, client, FALSE, control]; }; MakeFramesRelative: PROC [tube: Tube] ~ { vv: Triple _ Spline3d.Velocity[tube.coeffs, 0.0]; refVec: Triple _ Spline3d.RefVec[tube.coeffs, 0.0]; ApplyFramesRelative: TubeProc ~ { FOR i: NAT IN [0..TubeMisc.NFrames[tube]) DO f: Frame _ tube.frames[i]; p: Triple _ [f.matrix[3][0], f.matrix[3][1], f.matrix[3][2]]; -- ~ Spline3d.Position v: Triple _ [f.matrix[2][0], f.matrix[2][1], f.matrix[2][2]]; -- ~ Spline3d.Velocity s: REAL _ Vector3d.Length[v]; f.triad _ TubeGeometry.Basis[v, vv, refVec]; f.matrix _ TubeGeometry.RefMatrix[p, f.triad, s, 0.0, f.matrix]; ENDLOOP; }; TubeMisc.ApplyToTube[tube, ApplyFramesRelative]; }; NewTubes: PROC [p: ProgramData, tube: Tube] ~ { IF tube = NIL THEN RETURN; TubeGeometry.Make[p.tube1 _ tube, p.diameter.value, p.epsilon.value]; MakeFramesRelative[p.tube2 _ TubeMisc.Copy[p.tube1]]; }; TubeIn: Controls.ClickProc ~ { u: UserData _ UserDataFromClientData[clientData]; NewTubes[u.p, TubeIO.QueryAndReadTube[u.o]]; ViewerOps.PaintViewer[u.o.graphics, client, FALSE, u.o.buttons]; }; Toggle: PROC [clientData: REF ANY, type: DetailType, trueName, falseName: Rope.ROPE] ~ { u: UserData _ UserDataFromClientData[clientData]; TubeMisc.ToggleDetail[u.p.details, type, trueName, falseName, u.o]; ViewerOps.PaintViewer[u.o.graphics, client, FALSE, u.o.buttons]; }; TogLabel: ClickProc ~ {Toggle[clientData, label, "Label-On", "Label-Off"]}; TogSkel: ClickProc ~ {Toggle[clientData, skeleton, "Skel-On", "Skel-Off"]}; TogSpline: ClickProc ~ {Toggle[clientData, spline, "Splines-On", "Splines-Off"]}; TogContours: ClickProc ~ {Toggle[clientData, contours, "Contours-On", "Contours-Off"]}; TogLines: ClickProc ~ {Toggle[clientData, lines, "Lines-On", "Lines-Off"]}; TogFrames: ClickProc ~ {Toggle[clientData, frames, "Frames-On", "Frames-Off"]}; TogNormals: ClickProc ~ {Toggle[clientData, normals, "Normals-On", "Normals-Off"]}; UserDataFromClientData: PROC [clientData: REF ANY] RETURNS [u: UserData] ~ { u.p _ NARROW[(u.o _ NARROW[clientData]).data]; }; Commander.Register["///Commands/TubeCompare", TubeCompare, "\nTest TubeGeometry"]; Commander.Register["///Commands/TubeWeb", TubeWeb, "\nTest connecting two tubes."]; END. ¨TubeTestsImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Bloomenthal, February 24, 1987 6:14:48 pm PST Controls: Viewing: The tube: State: Κ’˜šœ™Jšœ Οmœ1™J˜?J˜:J˜J˜GJšœ˜—Jšœ*žœžœ˜6Jšœ˜J˜—š‘ œ˜&Jšœžœ˜Jšœžœ˜%J˜Jšœ žœ ˜J˜Jšœ*˜*JšœP˜PJšœP˜PJšœO˜OJšœR˜RJšœV˜VJšœVžœ˜\JšœU˜UJ˜J˜šžœžœžœ˜Kš œžœžœžœ žœ ˜>Jšœ%˜%Jšžœ˜Jšžœ žœ-˜CJ˜J˜—Jšœžœ ˜!šœ˜Jšœ˜šœ žœ˜JšœX˜XJšœE˜E—J˜J˜šœ žœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜—Jšœ˜Jšœ ˜ —J˜J˜—š‘ œ˜$Jšœžœ˜š’œžœžœ˜2J˜Jšžœžœžœžœ˜Jšœ=˜=Jšœ)˜)Jšœ8˜8Jšœ8˜8Jšœ2˜2Kšœ1˜1J˜—š’œžœ˜Jšœ˜J˜+J˜*Jšœ˜—Jšœ%˜%J˜J˜—šΠbn œ˜%Jšœžœ˜&Jšžœžœžœ˜(šžœ ž˜Jšœ"˜"šœ˜Jšœ0˜0Jšœ0˜0J˜—˜JšœH˜HJšœH˜HJ˜—Jšžœžœ˜—Jšœ0žœ ˜@J˜J˜—š’œžœ˜)K˜1K˜3š’œ˜!šžœžœžœž˜,J˜Jšœ> ˜TJšœ= ˜TJšœžœ˜Jšœ,˜,Jšœ@˜@Jšžœ˜—J˜—J˜0K˜K˜—š’œžœ!˜/Jšžœžœžœžœ˜KšœE˜EKšœ5˜5J˜J˜—š‘œ˜J˜1J˜,Jšœ,žœ˜@K˜K˜—š ’œžœžœžœ.žœ˜XJ˜1J˜JšœC˜CJšœ,žœ˜@J˜J˜—Jš‘œD˜LJš‘œF˜MJš‘ œJ˜SJš‘ œL˜WJš‘œE˜MJš‘ œH˜QJš‘ œJ˜TJ˜š ’œžœžœžœžœ˜LJšœžœžœ˜.J˜—J˜JšœR˜RJšœS˜SJ˜—šžœ˜J˜—J˜—…—!*)d