G3dProjectionsCmdImpl.mesa
Copyright Ó 1985, 1992 by Xerox Corporation. All rights reserved.
Bloomenthal, July 23, 1992 10:43 am PDT
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 <shape name>"]
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] ~ {
Swap y and z, so y corresponds to the vertical axis
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 <shape name>"];
END.