ImplicitEllipseCmdImpl.mesa
Copyright Ó 1989, 1990 by Xerox Corporation. All rights reserved.
Bloomenthal, November 21, 1992 6:02 pm PST
Wyvill, December 18, 1989 7:00:16 pm PST
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
Imported Types
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;
Local Types
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;
Implicit Design Command
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];
};
};
Ellipsoid Functions
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];
value ¬ BranchValue[d.tube];
};
Miscellany
Blink: PROC [message: ROPE] ~ {
MessageWindow.Append[message, TRUE];
MessageWindow.Blink[];
};
ImplicitDesign.Register["Ellipsoid", EllipsoidCommand, "metamorphosis tests."];
END.