<<>> <> <> <> DIRECTORY Commander, Controls, Draw2d, G2dBasic, G3dBasic, G3dControl, G3dDraw, G3dPolygon, G3dTool, G3dVector, Imager, ImplicitDesign, Rope; ImplicitBlendImpl: CEDAR PROGRAM IMPORTS Controls, G2dBasic, G3dBasic, G3dControl, G3dDraw, G3dPolygon, G3dTool, G3dVector, Imager, ImplicitDesign ~ BEGIN <> Triple: TYPE ~ G3dBasic.Triple; Polygon: TYPE ~ G3dPolygon.Polygon; Mode: TYPE ~ {union, sum, weight, fix}; Data: TYPE ~ RECORD [ tool: ImplicitDesign.Tool ¬ NIL, poly1, poly2: Polygon ¬ NIL, radius: REAL ¬ 0.25, mode: Mode ¬ weight]; Fig1: Commander.CommandProc ~ { MakePolygon: PROC [p1, p2, p3, p4: Triple] RETURNS [p: Polygon] ~ { pts: G3dBasic.TripleSequence ¬ G3dBasic.TripleSequenceFromList[LIST[p1, p2, p3, p4]]; p ¬ NEW[G3dPolygon.PolygonRep ¬ [points: pts, majorPlane: unknown]]; G3dPolygon.SetPolygon[polygon: p, accs: TRUE, normal: TRUE]; }; d: REF Data ¬ NEW[Data ¬ [ poly1: MakePolygon[[-.9, .3, 0], [-.9, .5, 0], [-.1, .5, 0], [-.1, .3, 0]], poly2: MakePolygon[[-.3, -.3, 0], [-.3, .3, 0], [-.1, .3, 0], [-.1, -.3, 0]]]]; d.tool ¬ ImplicitDesign.MakeTool[ name: "Figure 1", valueProc: Value, client: [data: d, draw: Draw], extraButtons: LIST[ Controls.ClickButton["Radius", Radius, d], Controls.ClickButton["Weight", ModeCycle, d]], toolSettings: [trackSize: .1, threshold: 0]]; G3dControl.UpdateControl[d.tool.renderTool.camera, d.tool.renderTool.camera.scale, 0.5]; }; SlowInOut: PROC [t: REAL] RETURNS [r: REAL] ~ {t2:REAL¬t*t; t3:REAL¬t*t2; r¬3.0*t2-t3-t3}; Value: ImplicitDesign.ValueProc ~ { d: REF Data ¬ NARROW[clientData]; n1: G3dPolygon.NearPolygon ¬ G3dPolygon.NearestToPolygon[d.poly1, point]; n2: G3dPolygon.NearPolygon ¬ G3dPolygon.NearestToPolygon[d.poly2, point]; v1: REAL ¬ d.radius/MAX[0.0001, n1.distance]-1.0; v2: REAL ¬ d.radius/MAX[0.0001, n2.distance]-1.0; SELECT d.mode FROM union => RETURN[MAX[v1, v2]]; sum => RETURN[v1+v2]; weight => RETURN[1.0-(1.0-v1)*(1.0-v2)]; fix => { n: Triple ¬ IF n1.distance < n2.distance THEN n1.point ELSE n2.point; v: Triple ¬ G3dVector.Unit[G3dVector.Sub[point, n]]; a: REAL ¬ (2.0/3.1415926535)*G2dBasic.ArcCos[ABS[G3dVector.Dot[v, d.poly1.normal]]]; sum: REAL ¬ v1+v2; union: REAL ¬ MAX[v1, v2]; a ¬ MIN[1.0, 0.15+a]; RETURN[sum+SlowInOut[1.0-a]*(union-sum)]; }; ENDCASE; }; Draw: Draw2d.DrawProc ~ { d: REF Data ¬ NARROW[clientData]; v: G3dTool.View ¬ G3dTool.GetView[viewer, d.tool.renderTool]; p1: G3dBasic.TripleSequence ¬ d.poly1.points; p2: G3dBasic.TripleSequence ¬ d.poly2.points; Imager.SetStrokeWidth[context, 10.0]; G3dDraw.DrawPolygon[context, NIL, NIL, p1, v.camera.matrix, v.viewport]; G3dDraw.DrawPolygon[context, NIL, NIL, p2, v.camera.matrix, v.viewport]; }; ModeCycle: Controls.ClickProc ~ { d: REF Data ¬ NARROW[clientData]; old: Mode ¬ d.mode; names: ARRAY Mode OF Rope.ROPE ¬ ["Union", "Sum", "Weight", "Fix"]; d.mode ¬ IF old = Mode.LAST THEN Mode.FIRST ELSE SUCC[old]; Controls.ButtonRelabel[d.tool.renderTool.outerData, names[old], names[d.mode]]; }; Radius: Controls.ClickProc ~ { d: REF Data ¬ NARROW[clientData]; d.radius ¬ Controls.TypescriptReadValue[d.tool.renderTool.typescript, "radius", d.radius]; }; ImplicitDesign.Register["Fig1", Fig1, "Fig1", "ImplicitDesign"]; <> <> <> <> <> <<>> <> <> <> <<};>> <<>> <> <> <> <> <> <> <> <> <> <> <<];>> <> <<};>> <<>> <> END.