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>"];