<<>> <> <> <> <> DIRECTORY Commander, Controls, Draw2d, G3dBasic, G3dMatrix, G3dTool, G3dTube, G3dVector, ImplicitDefs, ImplicitDesign, ImplicitPrimitives, ImplicitSurface, IO, MessageWindow, Rope; ImplicitEllipseCmdImpl: CEDAR PROGRAM IMPORTS Controls, G3dTube, G3dVector, ImplicitDesign, ImplicitPrimitives, ImplicitSurface, IO, MessageWindow, Rope ~ BEGIN <> Control: TYPE ~ Controls.Control; Quad: TYPE ~ G3dBasic.Quad; Segment: TYPE ~ G3dBasic.Segment; Matrix: TYPE ~ G3dMatrix.Matrix; Triple: TYPE ~ G3dVector.Triple; Tube: TYPE ~ G3dTube.Tube; TubeRep: TYPE ~ G3dTube.TubeRep; TubeProc: TYPE ~ G3dTube.TubeProc; Tool: TYPE ~ ImplicitDesign.Tool; ROPE: TYPE ~ Rope.ROPE; <> Data: TYPE ~ REF DataRep; DataRep: TYPE ~ RECORD [ tool: Tool ¬ NIL, tube1, tube2, tube: Tube ¬ NIL, length, width, height: Control ¬ NIL, count: INT ¬ 0 ]; Ellipsoid: TYPE ~ ImplicitPrimitives.Ellipsoid; EllipsoidRep: TYPE ~ ImplicitPrimitives.EllipsoidRep; <> EllipsoidCommand: Commander.CommandProc ~ { d: Data ~ NEW[DataRep]; d.tool ¬ ImplicitDesign.MakeTool[ name: "Ellipsoids", startProc: Start, valueProc: Value, client: [data: d, draw: Draw, stop: Stop], extraButtons: LIST [ Controls.ClickButton["Read Tube 1", GetTube, d, 1], Controls.ClickButton["Read Tube 2", GetTube, d, 1] ], extraControls: LIST[ d.length ¬ Controls.NewControl["Length",, d, 0.0, 2.0, 1.0, ESoidControl], d.width ¬ Controls.NewControl["Width",, d, 0.0, 2.0, 0.5, ESoidControl], d.height ¬ Controls.NewControl["Height",, d, 0.0, 2.0, 0.25, ESoidControl], ], toolSettings: [threshold: 1.0] ]; }; Stop: G3dTool.StopProc ~ { d: Data ¬ NARROW[clientData]; IF d.count > 1 THEN Controls.TypescriptWrite[d.tool.tool3d.typescript, IO.PutFR1["%g calls\n", IO.int[d.count]]]; }; Draw: G3dTool.DrawProc ~ { Inner: TubeProc ~ {ImplicitPrimitives.EllipsoidDraw[NARROW[tube.refAny], context, v]}; d: Data ¬ NARROW[clientData]; G3dTube.ApplyToTube[d.tube, Inner]; }; ESoidControl: Controls.ControlProc ~ {NewESoid[NARROW[clientData]]}; NewESoid: PROC [d: Data] ~ { PrepareTube[d.tube, d.length.value, d.width.value, d.height.value]; ImplicitDesign.Repaint[d.tool]; }; GetTube: Controls.ClickProc ~ { d: Data ¬ NARROW[clientData]; tube: Tube¬G3dTube.TubeFromFile[Controls.TypescriptReadFileName[d.tool.tool3d.typescript]]; IF tube = NIL THEN Blink["Can't read tube"] ELSE { G3dTube.SelectAll[tube]; G3dTube.Make[tube: tube, epsilon: 1.0]; d.tube ¬ G3dTube.CopyEntireTube[tube]; IF Rope.Equal[parent.name, "Read Tube 1"] THEN d.tube1 ¬ tube ELSE d.tube2 ¬ tube; NewESoid[d]; }; }; <> PrepareTube: PROC [tube: Tube, lengthScale, widthScale, heightScale: REAL] ~ { Inner: TubeProc ~ { tube.refAny ¬ ImplicitPrimitives.EllipsoidMake[ tube.p0, tube.p1, lengthScale, widthScale, heightScale, tube.refVec]; }; G3dTube.ApplyToTube[tube, Inner]; }; Start: ImplicitDefs.StartProc ~ { d: Data ~ NARROW[clientData]; d.count ¬ 0; IF nFrames # 0 AND d.tube1 # NIL AND d.tube2 # NIL THEN { alpha: REAL ¬ REAL[frame]/REAL[MIN[nFrames, nFrames-1]]; G3dTube.InterpTubes[d.tube1, d.tube2, d.tube, alpha]; }; IF d.tube # NIL THEN PrepareTube[d.tube, d.length.value, d.width.value, d.height.value]; IF d.tube = NIL THEN ImplicitDesign.StopTool[d.tool, "need tube"] ELSE { t: Tube ¬ d.tube; in: Triple ¬ G3dVector.Midpoint[t.p0, t.p1]; out: Triple ¬ G3dVector.Add[t.p0, G3dVector.Mul[G3dVector.Sub[t.p1, t.p0], -3]]; point ¬ ImplicitSurface.SurfacePoint[in, out, Value, d.tool.threshold, d]; }; }; NearestTube: PROC [q: Triple, tube: Tube] RETURNS [nearest: Tube] ~ { nearest ¬ tube; IF G3dTube.NBranches[tube, TRUE] # 0 THEN { Inner: TubeProc ~ { acc: Quad ¬ NARROW[tube.refAny, ImplicitPrimitives.Ellipsoid].acc; tube.nearSegment ¬ G3dVector.NearestToSegment[tube.p0, tube.p1, q, acc]; sqD ¬ G3dVector.SquareDistance[q, tube.nearSegment.point]; IF sqD < minSqD THEN {nearest ¬ tube; minSqD ¬ sqD}; }; sqD, minSqD: REAL ¬ 100000.0; G3dTube.ApplyToTube[tube, Inner]; }; }; Value: ImplicitDefs.ValueProc ~ { BranchesValue: PROC [tube: Tube] RETURNS [value: REAL ¬ 0.0] ~ { Inner: TubeProc ~ {value ¬ value+BranchValue[tube]}; G3dTube.ApplyToBranches[tube, Inner]; }; BranchValue: PROC [tube: Tube] RETURNS [value: REAL] ~ { value ¬ MAX[SegmentValue[tube], BranchesValue[tube]]; }; SegmentValue: PROC [tube: Tube] RETURNS [value: REAL ¬ 0.0] ~ { IF tube # NIL THEN { value ¬ ImplicitPrimitives.EllipsoidValue[point, NARROW[tube.refAny]]; d.count ¬ d.count+1; }; }; FooFoo: PROC [tube: Tube] RETURNS [value: REAL ¬ 0.0] ~ { Inner: TubeProc ~ {value ¬ value+SegmentValue[tube]}; G3dTube.ApplyToBranches[tube, Inner]; }; d: Data ¬ NARROW[clientData]; tube: Tube ¬ NearestTube[point, d.tube]; value ¬ SegmentValue[tube]; IF tube.prev # NIL THEN value ¬ value+tube.nearSegment.w0*SegmentValue[tube.prev]; value ¬ value+tube.nearSegment.w1*FooFoo[tube]; <> }; <> Blink: PROC [message: ROPE] ~ { MessageWindow.Append[message, TRUE]; MessageWindow.Blink[]; }; ImplicitDesign.Register["Ellipsoid", EllipsoidCommand, "metamorphosis tests."]; END.