G3dCleaveCmdImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Bloomenthal, November 8, 1992 1:24 pm PST
DIRECTORY Args, Commander, Controls, Convert, Draw2d, G2dBasic, G3dControl, G3dDraw, G3dMatrix, G3dModel, G3dPlane, G3dRender, G3dShape, G3dTool, G3dVector, Icons, Imager, IO, Real, Rope, ViewerOps, ViewerTools;
G3dCleaveCmdImpl: CEDAR PROGRAM
IMPORTS Args, Controls, Convert, G3dControl, G3dDraw, G3dMatrix, G3dModel, G3dPlane, G3dShape, G3dTool, G3dVector, Icons, IO, Real, Rope, ViewerOps, ViewerTools
~ BEGIN
Polygon Cleaver
Pair:     TYPE ~ G2dBasic.Pair;
Triple:    TYPE ~ G2dBasic.Triple;
IntegerPair:   TYPE ~ G2dBasic.IntegerPair;
Data:     TYPE ~ REF DataRep;
DataRep:    TYPE ~ RECORD [
cap:       BOOL ¬ TRUE,
setPlane, setSeparation:  Controls.Button,
slice:       G3dControl.Slice,
d:        Controls.Control,
tool:       G3dTool.Tool,
picks:       ARRAY [0..3) OF G3dTool.ShapePoint
];
CommandProc: Commander.CommandProc ~ {
d: Data ¬ NEW[DataRep];
arg: Rope.ROPE ¬ Args.GetRope[cmd];
IF arg = NIL AND G3dTool.GetActiveTool[] = NIL
THEN RETURN[$Failure, "Please specify a shape file."];
d.d ¬ Controls.NewControl["d", vSlider, d, -1.0, 1.0, 0.0, DControl];
d.slice ¬ G3dControl.InitSlice[proc: SliceControl, data: d];
Controls.ControlRow[d.slice.x, 1];
d.tool ¬ G3dTool.MakeTool[
name: Rope.Concat["3dCleave ", Args.GetRope[cmd]],
extraControls: LIST[d.slice.x, d.slice.y, d.slice.z, d.d, d.slice.theta, d.slice.phi],
extraButtons: LIST[
Controls.ClickButton["Cap: On", ToggleCap, , 1d],
d.setSeparation ¬ Controls.TextButton["Separation: ", "0.05\t",, d, 1],
d.setPlane ¬ Controls.TextButton["Plane: ", "0.000\t1.000\t0.000\t0.000", SetPlane, d, 1],
Controls.ClickButton["FitPlane", FitPlane, d, 1],
Controls.ClickButton["CLEAVE", Cleave, d, 1]],
client: [data: d, draw: Draw, mouse: Mouse, change: Change],
icon: icon,
useExistingTool: arg = NIL,
noOpen: TRUE];
IF arg # NIL AND (msg ¬ G3dTool.ReadFromShapeFile[d.tool, arg, TRUE]) # NIL THEN {
ViewerOps.DestroyViewer[d.tool.outer];
RETURN[$Failure, msg];
};
d.tool.shapes[0].selected ¬ TRUE;
ViewerOps.OpenIcon[d.tool.outer];
};
Cleave: Controls.ClickProc ~ {
AddShape: PROC [s: G3dShape.Shape, name: Rope.ROPE, sep: REAL, color: Triple] ~ {
translate: Triple ¬ G3dVector.Mul[[d.slice.plane.x, d.slice.plane.y, d.slice.plane.z], sep];
FOR i: INT IN [0..s.vertices.length) DO s.vertices[i].color ¬ color; ENDLOOP;
s.name ¬ name;
s.vertices.valid[color] ¬ TRUE;
s.showBackfaces ¬ TRUE;
s.selected ¬ TRUE;
G3dShape.TransformShape[s, translate];
G3dTool.AddShape[d.tool, s];
};
d: Data ¬ NARROW[clientData];
shapes: G3dShape.ShapeSequence;
sep: REAL ¬ Convert.RealFromRope[ViewerTools.GetContents[d.setSeparation.textViewer]];
IF d.tool.shapes = NIL THEN RETURN;
FOR i: INTEGER IN [0..d.tool.shapes.length) DO
shapes ¬ G3dShape.AddToShapeSequence[shapes, d.tool.shapes[i]];
ENDLOOP;
FOR i: INTEGER IN [0..d.tool.shapes.length) DO G3dTool.DeleteShapeEntry[d.tool, i]; ENDLOOP;
FOR i: INTEGER IN [0..shapes.length) DO
neg, pos: G3dShape.Shape;
[neg, pos] ¬ G3dModel.Cleave[shapes[i], d.slice.plane, d.cap];
AddShape[pos, Rope.Concat[shapes[i].name, ".grn"], sep, [0.0, 1.0, 0.0]];
AddShape[neg, Rope.Concat[shapes[i].name, ".blu"], -sep, [0.0, 0.0, 1.0]];
ENDLOOP;
G3dTool.Repaint[d.tool];
};
Draw: G3dTool.DrawProc ~ {
d: Data ~ NARROW[clientData];
IF whatChanged = $Overlay THEN {
DrawSlice: PROC ~ {
IP: PROC [p: Pair] RETURNS [i: IntegerPair] ~ {i ¬ [Real.Round[p.x], Real.Round[p.y]]};
VP: PROC [p: Pair] RETURNS [v: Pair] ~ {v ¬ G3dMatrix.TransformByViewport[p, vp]};
x: G3dMatrix.Matrix ¬ view;
m: G3dMatrix.Matrix ~ G3dMatrix.Mul[s.matrix, x];
a: ARRAY [0..4) OF IntegerPair;
q: ARRAY [0..4) OF Pair ¬ [[-1.0, 1.0], [1.0, 1.0], [1.0, -1.0], [-1.0, -1.0]];
c: Triple ¬ G3dMatrix.TransformPair[[0.0, 0.0], s.matrix];
G3dDraw.SetColor[context, [1.0, 0.0, 0.0]];
FOR i: INT IN[0..4) DO a[i] ¬ IP[VP[G3dMatrix.TransformPairD[q[i],m]]]; ENDLOOP;
FOR i: INT IN [0..4) DO G3dDraw.Line2d[context, a[i], a[(i+1) MOD 4], solid]; ENDLOOP;
G3dDraw.Vector[context, c, [-s.plane.x, -s.plane.y, -s.plane.z], x, vp,, 0.1];
G3dDraw.SetColor[context, [1.0, 0.0, 1.0]];
FOR i: INTEGER IN [0..3) DO
pick: G3dTool.ShapePoint ¬ d.picks[i];
IF pick # [] THEN {
pos: IntegerPair ¬ v.screens[pick.shape][pick.point].intPos;
p1: IntegerPair ¬ [pos.x-3, pos.y-3];
p2: IntegerPair ¬ [pos.x+3, pos.y+3];
G3dDraw.Quadrangle[context, p1.x, p1.y, p1.x, p2.y, p2.x, p2.y, p2.x, p1.y];
};
ENDLOOP;
};
s: G3dControl.Slice ¬ d.slice;
IF s # NIL AND s.matrix # NIL THEN DrawSlice[];
};
};
NewPlane: PROC [d: Data, whatChanged: REF ¬ NIL] ~ {
p: G3dControl.Plane ¬ d.slice.plane;
ViewerTools.SetContents[d.setPlane.textViewer, IO.PutFLR["%5.3f %5.3f %5.3f %5.3f",
LIST[IO.real[p.x], IO.real[p.y], IO.real[p.z], IO.real[p.w]]]];
G3dTool.Repaint[d.tool, $Restore];
G3dTool.Repaint[d.tool, $Overlay];
};
Mouse: Controls.MouseProc ~ {
IF mouse.state = down THEN {
d: Data ¬ NARROW[clientData];
sp: G3dTool.ShapePoint ¬ G3dTool.ScreenPick[d.tool, viewer, mouse.pos];
FOR i: INTEGER IN [0..3) DO
IF d.picks[i] = [] THEN {d.picks[i] ¬ sp; EXIT};
IF d.picks[i] = sp THEN {d.picks[i] ¬ []; EXIT};
REPEAT FINISHED => RETURN;
ENDLOOP;
G3dTool.Repaint[d.tool, $Restore];
G3dTool.Repaint[d.tool, $Overlay];
};
};
Change: G3dTool.ChangeProc ~ {NARROW[clientData, Data].tool^ ¬ G3dTool.GetActiveTool[]^};
SliceControl: Controls.ControlProc ~ {
IF control.mouse.state # up THEN {
d: Data ¬ NARROW[control.clientData];
G3dControl.UpdateSlice[d.slice];
NewPlane[d];
};
};
DControl: Controls.ControlProc ~ {
IF control.mouse.state = up
THEN Controls.Reset[control]
ELSE {
d: Data ¬ NARROW[control.clientData];
d.slice.plane.w ¬ d.slice.plane.w-Controls.GetSliderDialDeltaValue[control];
G3dControl.SetSlice[d.slice, d.slice.plane, d.slice.size.value];
NewPlane[d];
};
};
FitPlane: Controls.ClickProc ~ {
d: Data ¬ NARROW[clientData];
t: ARRAY [0..3) OF Triple;
FOR i: INTEGER IN [0..3) DO IF d.picks[i] = [] THEN RETURN; ENDLOOP;
FOR i: INTEGER IN [0..3) DO
t[i] ¬ d.tool.shapes[d.picks[i].shape].vertices[d.picks[i].point].point;
ENDLOOP;
FOR i: INTEGER IN [0..3) DO d.picks[i] ¬ []; ENDLOOP;
G3dControl.SetSlice[d.slice, G3dPlane.FromThreePoints[t[0], t[1], t[2], TRUE], d.slice.size.value];
NewPlane[d];
};
SetPlane: Controls.ClickProc ~ {
d: Data ¬ NARROW[clientData];
s: IO.STREAM ¬ IO.RIS[ViewerTools.GetContents[d.setPlane.textViewer]];
x: REAL ¬ -IO.GetReal[s]; y: REAL ¬ -IO.GetReal[s]; z: REAL ¬ -IO.GetReal[s];
G3dControl.SetSlice[d.slice, [x, y, z, IO.GetReal[s]], d.slice.size.value];
NewPlane[d];
};
ToggleCap: Controls.ClickProc ~ {
d: Data ¬ NARROW[clientData];
Controls.ButtonToggle[d.tool.outerData, d.cap ¬ NOT d.cap, "Cap: On", "Cap: Off"];
};
icon: Icons.IconFlavor ¬ Icons.NewIconFromFile["G3dUser.icons", 3];
G3dTool.Register["Cleave", CommandProc, "cleave [FileName]"];
END.