<<>> <> <> <> 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 <> 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.