<<>> <> <> <> DIRECTORY Commander, Controls, G3dDraw, G3dTool, G3dVector, ImplicitDefs, ImplicitOctree, Rope; ImplicitIFEPTCmdImpl: CEDAR PROGRAM IMPORTS Commander, Controls, G3dDraw, G3dVector, ImplicitOctree ~ BEGIN <> 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] ]; <> data.s1 ¬ MakeSphere[[0.0, 0.0, 0.0], 0.6]; <> data.s2 ¬ MakeSphere[[0.5, 0.0, 0.0], 0.55]; data.s3 ¬ MakeSphere[[-0.5, 0.0, 0.0], 0.55]; <> 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]; <> 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 ~ { <> <<(S1) centered on origin with radius = 70; 544 triangles, 6324 evaluations>> <> <<(S2) sphere at (-120, 0, 0) with radius 70>> <<(S3) sphere at (120, 0, 0) with radius 70>> <> <<1000 triangles, 8570 evaluations>> <> <<(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),>> <> <<3318 triangles, 19875 evaluations>> <> <<(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]; }; <> Commander.Register["IFEPT", IFEPT, "compute Implicit Function Evaluations Per Triangle"]; END.