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. Β G3dProjectionsCmdImpl.mesa Copyright Σ 1985, 1992 by Xerox Corporation. All rights reserved. Bloomenthal, July 23, 1992 10:43 am PDT Swap y and z, so y corresponds to the vertical axis ΚΗ–"cedarcode" style•NewlineDelimiter ™šœ™Jšœ Οeœ6™BJ™'J˜JšΟk œq˜zJ˜—šΠlnœžœž˜$Jšžœ[˜b—šœž˜J˜šœžœžœ˜J˜)Jšœ˜Jšœžœ˜Jšœ˜Jšœ˜J˜—šΟb œ˜%J˜<šžœ˜Jšžœžœ)˜4šžœ˜Jšœžœžœ˜Jš œΟsœ‘œ‘œ‘œ‘žœ˜SJšžœžœžœžœ˜(˜#J˜'J˜J˜šœ žœ˜Jšœ*˜*Jšœ)˜)Jšœ)˜)Jšœ)˜)Jšœ(˜(Jšœ1˜1—Jšœ žœ˜J˜J˜—J˜"J˜——J˜J˜—šœžœ˜-J˜—šΟnœ˜Jšœžœžœ˜)J˜Jšœ*žœ˜1Jšœ˜J˜—š’œ˜Jšœžœžœ ˜!Jšœ žœ˜šžœžœž˜J˜OJ˜NJšžœ˜—Jšœ6˜6Jšœ*žœ˜1J˜J˜—š’œ˜Jšœžœžœ ˜!šžœžœžœž˜-J˜)J˜šžœžœž˜J˜@J˜@J˜@Jšžœ˜—Jšžœ˜—Jšœ*žœ˜1J˜J˜—š’ œ˜!Jšœžœžœ ˜!Jšœžœ;˜NJšžœ žœžœžœ˜Jš œ‘œ‘œ‘œ‘œžœ˜HJšœ*žœ˜1Jšžœ‘œ*žœ˜VJ˜J˜—š’œ˜Jšœžœžœ ˜!Jšœžœ;˜NJšžœ žœžœ%˜;J˜J˜—JšœžœΟc˜;šœžœ£3˜RJ˜—š’œ˜š’œžœ˜š’œžœžœžœ˜5J™3J˜/šžœž˜J˜4˜ Jšœžœ˜!J˜J˜—Jšžœ˜—J˜-J˜—Jšœžœžœ ˜!J˜'Jšœžœžœžœ žœ žœ žœ žœ žœ ˜[Jš œžœžœ žœžœžœžœ˜RJš œžœ žœžœžœ‘œ˜Xšžœžœžœž˜-J˜=Jšœžœ˜$šžœžœžœž˜$Jšœžœ˜J˜/J˜Jšžœ˜—Jšžœ˜—J˜—J˜%˜J˜——J˜@J˜—šžœ˜J˜——…—¬5