<<>> <> <> <> DIRECTORY Commander, CommanderOps, Controls, Draw2d, G3dBasic, G3dControl, G3dDraw, G3dTool, G3dMatrix, G3dModel, G3dShape, IO, MessageWindow, Rope, ViewerOps; G3dPolygonProxCmdImpl: CEDAR PROGRAM IMPORTS CommanderOps, Controls, G3dControl, G3dDraw, G3dModel, G3dTool, G3dShape, IO, MessageWindow, ViewerOps ~ BEGIN <> <> <> Data: TYPE ~ REF DataRep; DataRep: TYPE ~ RECORD [ tool: G3dTool.Tool ¬ NIL, shape: G3dShape.Shape ¬ NIL, -- the polyhedron hold: G3dControl.Hold ¬ NIL, -- point/vector adjustment mode: {vector, point} ¬ point, -- ray-intersec or point-prox? near: G3dModel.NearModel ¬ [], -- proximity to the shape vector: G3dBasic.Triple ¬ [0.0, 0.0, 0.0], -- direction of the ray point: G3dBasic.Triple ¬ [0.0, 0.0, 0.0] -- arbitrary point in space ]; PolygonProx: Commander.CommandProc ~ { argv: CommanderOps.ArgumentVector ¬ CommanderOps.Parse[cmd]; IF argv.argc # 2 THEN RETURN[$Failure, polygonProxUsage] ELSE { d: Data ¬ NEW[DataRep]; d.shape ¬ G3dShape.ShapeFromFile[argv[1] ! G3dShape.Error => {msg ¬ reason; GOTO Bad}]; d.hold ¬ G3dControl.InitHold[Hold, d]; d.tool ¬ G3dTool.MakeTool[ name: "Proximity Tester", extraButtons: LIST[Controls.ClickButton["Point Mode", ToggleMode, d]], extraControls: LIST[d.hold.pitch, d.hold.yaw, d.hold.x, d.hold.y, d.hold.z], controlSizes: [20, 200, 55, 20, 55, 150, 150], client: [data: d, draw: Draw], noOpen: TRUE]; G3dTool.AddShape[d.tool, d.shape]; d.vector ¬ G3dControl.VectorFromHold[d.hold]; d.point ¬ G3dControl.PositionFromHold[d.hold]; ViewerOps.OpenIcon[d.tool.outer]; }; EXITS Bad => RETURN[$Failure, msg]; }; ComputeProximity: PROC [d: Data] ~ { Message: PROC [r: Rope.ROPE] ~ { t: G3dBasic.Triple ¬ d.near.point; r ¬ IO.PutFLR["\t\t%g polygon %g at [%6.3f, %6.3f, %6.3f]", LIST[IO.rope[r], IO.int[d.near.nPolygon], IO.real[t.x], IO.real[t.y], IO.real[t.z]]]; MessageWindow.Append[r, TRUE]; }; SELECT d.mode FROM vector => { d.near ¬ G3dModel.IntersectWithRay[d.shape, [d.point, d.vector]]; IF d.near.noIntersection THEN MessageWindow.Append["No intersection found", TRUE] ELSE Message["Intersect"]; }; ENDCASE => { d.near ¬ G3dModel.ClosestPoint[d.shape, d.point]; Message["Closest to"]; }; }; Hold: G3dControl.ControlProc ~ { d: Data ¬ NARROW[control.clientData]; SELECT control FROM d.hold.pitch, d.hold.yaw => { IF d.mode # vector THEN RETURN; d.vector ¬ G3dControl.VectorFromHold[d.hold]; }; ENDCASE => d.point ¬ G3dControl.PositionFromHold[d.hold]; ComputeProximity[d]; G3dTool.Repaint[d.tool]; }; Draw: G3dTool.DrawProc ~ { d: Data ~ NARROW[clientData]; IF d.mode = vector THEN G3dDraw.Vector[context, d.point, d.vector, view, vp,,,, cross] ELSE G3dDraw.Mark[context, d.point, view, vp,, cross]; IF NOT d.near.noIntersection THEN G3dDraw.Mark[context, d.near.point, view, vp,, asterisk]; }; ToggleMode: Controls.ClickProc ~ { d: Data ¬ NARROW[clientData]; d.mode ¬ IF d.mode = vector THEN point ELSE vector; Controls.ButtonToggle[d.tool.outerData, d.mode = vector, "Vector Mode", "Point Mode"]; ComputeProximity[d]; G3dTool.Repaint[d.tool]; }; <> polygonProxUsage: Rope.ROPE ~ "PolygonProx "; G3dTool.Register["PolygonProx", PolygonProx, polygonProxUsage]; END.