ImplicitIFEPTCmdImpl.mesa
Copyright Ó 1993 by Xerox Corporation. All rights reserved.
Bloomenthal, February 28, 1993 0:39 am PST
DIRECTORY Commander, Controls, G3dDraw, G3dTool, G3dVector, ImplicitDefs, ImplicitOctree, Rope;
ImplicitIFEPTCmdImpl: CEDAR PROGRAM
IMPORTS Commander, Controls, G3dDraw, G3dVector, ImplicitOctree
~ BEGIN
IFEPT (Implicit Function Evaluations Per Triangles) Counter
Triple:       TYPE ~ G3dVector.Triple;
Object:       TYPE ~ {sphere, blend, lines, penguin};
Sphere:       TYPE ~ RECORD [center: Triple, radius, rSq: REAL];
Cylinder:      TYPE ~ RECORD [p1, p2: Triple, rSq: REAL, acc: G3dVector.Quad];
Data:        TYPE ~ RECORD [
tool:          ImplicitOctree.Tool,
object:         Object ¬ blend,
c1, c2, c3, c4, c5, c6, c7, c8, c9, c10: Cylinder,
s1, s2, s3, s4, s5, s6:      Sphere
];
IFEPT: Commander.CommandProc ~ {
MakeCylinder: PROC [p1, p2: Triple, radius: REAL] RETURNS [c: Cylinder] ~ {
c ¬ [p1, p2, radius*radius, G3dVector.NearnessAccelerator[p1, p2]];
};
MakeSphere: PROC [center: Triple, radius: REAL] RETURNS [s: Sphere] ~ {
s ¬ [center, radius, radius*radius];
};
data: REF Data ¬ NEW[Data];
data.tool ¬ ImplicitOctree.MakeTool[
name: "IFEPT Counter for Adaptive Polygonization",
valueProc: Value,
startProc: Start,
client: [data: data, draw: Draw],
extraButtons: LIST[Controls.ClickButton["Blend", CycleObject, data]],
toolSettings: [
edgeMode: binarySectioning,
threshold: 0.0,
octreeType: track,
trackSize: 0.15,
adaptDuringMax: 2,
flatness: 75.0]
];
sphere:
data.s1 ¬ MakeSphere[[0.0, 0.0, 0.0], 0.6];
blend:
data.s2 ¬ MakeSphere[[0.5, 0.0, 0.0], 0.55];
data.s3 ¬ MakeSphere[[-0.5, 0.0, 0.0], 0.55];
lines:
data.c1 ¬ MakeCylinder[[-0.5, -0.5, 0.0], [-0.5, 1.0, 0], 0.125];
data.c2 ¬ MakeCylinder[[-0.5, 0.5, 0.0], [0.5, 0.5, 0], 0.125];
data.c3 ¬ MakeCylinder[[0.5, 0.5, 0.0], [0.5, -0.5, 0], 0.125];
penguin:
data.s4 ¬ MakeSphere[[0.0, 0.0, 1.0], 0.23];
data.s5 ¬ MakeSphere[[0.0, 0.09, 1.0], 0.15];
data.s6 ¬ MakeSphere[[0.0, 0.14, 0.91], 0.17];
data.c4 ¬ MakeCylinder[[0.0, 0.15, 0.92], [0.01, 0.1, 0.7], 0.06];
data.c5 ¬ MakeCylinder[[0.03, 0.0, 1.0], [0.05, -0.12, 1.0], 0.05];
data.c6 ¬ MakeCylinder[[0.03, 0.0, 1.0], [-0.05, -0.12, 1.0], 0.05];
data.c7 ¬ MakeCylinder[[0.03, 0.1, 1.0], [0.11, 0.08, 0.92], 0.05];
data.c8 ¬ MakeCylinder[[0.03, 0.1, 1.0], [-0.11, 0.08, 0.92], 0.05];
data.c9 ¬ MakeCylinder[[0.05, -.12, 1.0], [0.05, -.12, 0.95], 0.05];
data.c10 ¬ MakeCylinder[[0.05, -.12, 1.0], [-0.05, -0.12, 0.95], 0.05];
};
Start: ImplicitDefs.StartProc ~ {
data: REF Data ¬ NARROW[clientData];
point ¬ SELECT data.object FROM
lines => [-0.625, 0.0, 0.0],
ENDCASE => [];
};
Value: ImplicitDefs.ValueProc ~ {
Sphere
(S1) centered on origin with radius = 70; 544 triangles, 6324 evaluations
Blend
(S2) sphere at (-120, 0, 0) with radius 70
(S3) sphere at (120, 0, 0) with radius 70
blend with 1/r
1000 triangles, 8570 evaluations
Lines
(the following values divided by 200)
(C1) cylinder from (-100, -100, 0) to (-100, 200, 0)
(C2) cylinder from (-100, 100, 0) to (100, 100, 0)
(C3) cylinder from (100, 100, 0) to (100, -100, 0),
each with radius 25
3318 triangles, 19875 evaluations
Penguin: the following lines and spheres:
(the following values divided by 1000)
(C4) cylinder from (0, 150, 920) (10, 100, 700) with radius 6
(C5) cylinder from (30, 0, 1000) to (50, -120, 1000) with radius 5
(C6) cylinder from (30, 0, 1000) to (-50, -120, 1000) with radius 5
(C7) cylinder from (30, 100, 1000) to (110, 80, 920) with radius 5
(C8) cylinder from (30, 100, 1000) to (-110, 80, 920) with radius 5
(C9) cylinder from (50, -120, 1000) to (50, -120, 950) with radius 5
(C10) cylinder from (50, -120, 1000) to (-50, -120, 950) with radius 5
(S4) sphere at (0, 0, 1000) with radius 23
(S5) sphere at (0, 90, 1000) with radius 15
(S6) sphere at (0, 150, 910) with radius 17
OfCylinder: PROC [c: Cylinder] RETURNS [value: REAL] ~ {
n: G3dVector.NearSegment ~ G3dVector.NearestToSegment[c.p1, c.p2, point, c.acc];
value ¬ c.rSq/MAX[0.001, G3dVector.SquareDistance[point, n.point]];
};
OfSphere: PROC [s: Sphere] RETURNS [value: REAL] ~ {
value ¬ s.rSq/MAX[0.001, G3dVector.SquareDistance[point, s.center]];
};
data: REF Data ¬ NARROW[clientData];
value ¬ SELECT data.object FROM
sphere => OfSphere[data.s1]-1.0,
blend => OfSphere[data.s2]+OfSphere[data.s3]-2.0, 
lines => OfCylinder[data.c1]+OfCylinder[data.c2]+OfCylinder[data.c3]-1.0, 
penguin =>
OfCylinder[data.c4]+OfCylinder[data.c5]+OfCylinder[data.c6]+
OfCylinder[data.c7]+OfCylinder[data.c8]+OfCylinder[data.c9]+OfCylinder[data.c10]+
OfSphere[data.s4]+OfSphere[data.s5]+OfSphere[data.s6]-1.0,
ENDCASE => ERROR;
};
Draw: G3dTool.DrawProc ~ {
data: REF Data ¬ NARROW[clientData];
G3dDraw.SetColor[context, [0, 1, 0]];
SELECT data.object FROM
sphere => G3dDraw.Sphere[context, data.s1.center, data.s1.radius, 5, view, vp];
blend => {
G3dDraw.Sphere[context, data.s2.center, data.s2.radius, 5, view, vp];
G3dDraw.Sphere[context, data.s3.center, data.s3.radius, 5, view, vp];
};
lines => {
G3dDraw.Segment[context, data.c1.p1, data.c1.p2, view, vp];
G3dDraw.Segment[context, data.c2.p1, data.c2.p2, view, vp];
G3dDraw.Segment[context, data.c3.p1, data.c3.p2, view, vp];
};
penguin => {
G3dDraw.Sphere[context, data.s4.center, data.s4.radius, 5, view, vp];
G3dDraw.Sphere[context, data.s5.center, data.s5.radius, 5, view, vp];
G3dDraw.Sphere[context, data.s6.center, data.s6.radius, 5, view, vp];
G3dDraw.Segment[context, data.c4.p1, data.c4.p2, view, vp];
G3dDraw.Segment[context, data.c5.p1, data.c5.p2, view, vp];
G3dDraw.Segment[context, data.c6.p1, data.c6.p2, view, vp];
G3dDraw.Segment[context, data.c7.p1, data.c7.p2, view, vp];
G3dDraw.Segment[context, data.c8.p1, data.c8.p2, view, vp];
G3dDraw.Segment[context, data.c9.p1, data.c9.p2, view, vp];
G3dDraw.Segment[context, data.c10.p1, data.c10.p2, view, vp];
};
ENDCASE;
G3dDraw.SetColor[context, [1, 0, 0]];
};
CycleObject: Controls.ClickProc ~ {
Roper: PROC [object: Object] RETURNS [r: Rope.ROPE] ~ {
r ¬ SELECT object FROM
sphere => "Sphere",
blend => "Blend",
lines => "Lines",
penguin => "Penguin",
ENDCASE => NIL;
};
data: REF Data ¬ NARROW[clientData];
old: Object ~ data.object;
data.object ¬ IF old = Object.LAST THEN Object.FIRST ELSE SUCC[old];
SELECT data.object FROM
sphere, blend => data.tool.trackSize ¬ 0.25;
lines, penguin => data.tool.trackSize ¬ 0.1;
ENDCASE;
Controls.ButtonRelabel[data.tool.tool3d.outerData, Roper[old], Roper[data.object]];
ImplicitOctree.Repaint[data.tool];
};
Initialization
Commander.Register["IFEPT", IFEPT, "compute Implicit Function Evaluations Per Triangle"];
END.