<<>> <> <> <> DIRECTORY Commander, CommanderOps, Controls, Draw2d, G3dBasic, G3dShape, G3dTool, MessageWindow, RealFns, Rope, ViewerOps; G3dProjectionsCmdImpl: CEDAR PROGRAM IMPORTS CommanderOps, Controls, Draw2d, G3dShape, G3dTool, MessageWindow, RealFns, Rope, ViewerOps ~ BEGIN Data: TYPE ~ RECORD [ type: {cavalier, isometric} ¬ cavalier, graphics: Draw2d.Viewer, scale: REAL ¬ 1.0, shape: G3dShape.Shape, outerData: Controls.OuterData]; ProjectCmd: Commander.CommandProc ~ { argv: CommanderOps.ArgumentVector ¬ CommanderOps.Parse[cmd]; IF argv.argc # 2 THEN RETURN[$Failure, "Usage: Project "] ELSE { d: REF Data ¬ NEW[Data]; d.shape ¬ G3dShape.ShapeFromFile[argv[1] ! G3dShape.Error=>{msg¬reason; CONTINUE}]; IF msg # NIL THEN RETURN[$Failure, msg]; d.outerData ¬ Controls.OuterViewer[ name: Rope.Concat["Project ", argv[1]], graphicsHeight: 300, drawProc: DrawProc, buttons: LIST[ Controls.ClickButton["Cavalier", Type, d], Controls.ClickButton["Swap XY", Swap, d], Controls.ClickButton["Swap YZ", Swap, d], Controls.ClickButton["Swap XZ", Swap, d], Controls.ClickButton["IPOut", IPOut, d], Controls.ClickButton["ReadShape", ReadShape, d]], controls: LIST[Controls.NewControl[name: "Scale", type: hSlider, clientData: d, max: 2.0, init: 1.0, proc: Scale, taper: exp, textLocation: [left, center]]], typescriptHeight: 18, clientData: d]; d.graphics ¬ d.outerData.graphics; }; }; oneOverSqRtTwo: REAL ~ 1.0/RealFns.SqRt[2.0]; Scale: Controls.ControlProc ~ { d: REF Data ¬ NARROW[control.clientData]; d.scale ¬ control.value; ViewerOps.PaintViewer[d.graphics, client, FALSE]; }; Type: Controls.ClickProc ~ { d: REF Data ¬ NARROW[clientData]; new: Rope.ROPE; SELECT TRUE FROM Rope.Equal[parent.name, "Cavalier"] => {new ¬ "Isometric"; d.type ¬ isometric}; Rope.Equal[parent.name, "Isometric"] => {new ¬ "Cavalier"; d.type ¬ cavalier}; ENDCASE; Controls.ButtonRelabel[d.outerData, parent.name, new]; ViewerOps.PaintViewer[d.graphics, client, FALSE]; }; Swap: Controls.ClickProc ~ { d: REF Data ¬ NARROW[clientData]; FOR n: NAT IN [0..d.shape.vertices.length) DO v: G3dShape.Vertex ¬ d.shape.vertices[n]; p: G3dBasic.Triple ¬ v.point; SELECT TRUE FROM Rope.Equal[parent.name, "Swap XY"] => v.point ¬ [p.y, p.x, p.z]; Rope.Equal[parent.name, "Swap YZ"] => v.point ¬ [p.x, p.z, p.y]; Rope.Equal[parent.name, "Swap XZ"] => v.point ¬ [p.z, p.y, p.x]; ENDCASE; ENDLOOP; ViewerOps.PaintViewer[d.graphics, client, FALSE]; }; ReadShape: Controls.ClickProc ~ { d: REF Data ¬ NARROW[clientData]; fileName: Rope.ROPE ¬ Controls.TypescriptReadFileName[d.outerData.typescript]; IF fileName = NIL THEN RETURN; d.shape ¬ G3dShape.ShapeFromFile[fileName ! G3dShape.Error=> GOTO Cant]; ViewerOps.PaintViewer[d.graphics, client, FALSE]; EXITS Cant => {MessageWindow.Append["Can't read shape", TRUE]; MessageWindow.Blink[]}; }; IPOut: Controls.ClickProc ~ { d: REF Data ¬ NARROW[clientData]; fileName: Rope.ROPE ¬ Controls.TypescriptReadFileName[d.outerData.typescript]; IF fileName # NIL THEN Draw2d.IPOut[fileName, DrawProc, d]; }; a: REAL ¬ RealFns.SqRt[2.0]/2.0; -- = RealFns.CosDeg[-45.0] b: REAL ¬ a/RealFns.SqRt[3.0]; -- = -RealFns.SinDeg[-45.0]*RealFns.SinDeg[35.2639] DrawProc: Draw2d.DrawProc ~ { Action: PROC ~ { GetPair: PROC [n: NAT] RETURNS [p: G3dBasic.Pair] ~ { <> v: G3dBasic.Triple ¬ d.shape.vertices[n].point; SELECT d.type FROM isometric => p ¬ [(v.x-v.z)*a, (v.x+v.z-2.0*v.y)*b]; cavalier => { zPart: REAL ¬ v.y*oneOverSqRtTwo; p ¬ [v.x+zPart, v.z+zPart]; }; ENDCASE; p ¬ [p.x*scale+offset.x, p.y*scale+offset.y]; }; d: REF Data ¬ NARROW[clientData]; i: G3dBasic.Box ¬ d.shape.objectExtent; s: REAL¬MAX[ABS[i.min.x],ABS[i.min.y],ABS[i.min.z],ABS[i.max.x],ABS[i.max.y],ABS[i.max.z]]; scale: REAL ¬ s*d.scale*(IF viewer # NIL THEN MAX[viewer.ww, viewer.wh] ELSE 500); offset: G3dBasic.Pair ¬ IF viewer # NIL THEN [viewer.ww/2, viewer.wh/2] ELSE [250, 250]; FOR n: NAT IN [0..d.shape.surfaces.length) DO polygon: G3dBasic.NatSequence ¬ d.shape.surfaces[n].vertices; n0: NAT ¬ polygon[polygon.length-1]; FOR p: NAT IN [0..polygon.length) DO n1: NAT ¬ polygon[p]; Draw2d.Line[context, GetPair[n0], GetPair[n1]]; n0 ¬ n1; ENDLOOP; ENDLOOP; }; Draw2d.DoWithBuffer[context, Action]; }; G3dTool.Register["Project", ProjectCmd, "project "]; END.