DIRECTORY Commander, CommanderOps, Controls, Draw2d, G3dBasic, G3dCubeDraw, G3dDraw, G3dMatrix, G3dOctree, G3dTool, Imager, MessageWindow, Rope, ViewerClasses; G3dVolumeCmdsAImpl: CEDAR PROGRAM IMPORTS CommanderOps, Controls, G3dCubeDraw, G3dDraw, G3dOctree, G3dTool, Draw2d, Imager, MessageWindow, Rope ~ BEGIN OPEN G3dOctree; Viewer: TYPE ~ ViewerClasses.Viewer; Context: TYPE ~ Imager.Context; Control: TYPE ~ Controls.Control; ClickProc: TYPE ~ Controls.ClickProc; Matrix: TYPE ~ G3dMatrix.Matrix; DrawData: TYPE ~ REF DrawDataRec; DrawDataRec: TYPE ~ RECORD [ tool: G3dTool.Tool ¬ NIL, -- parent viewer pendant: BOOL ¬ FALSE, -- if desired labels: BOOL ¬ FALSE, -- if desired lineThickness: Control ¬ NIL, -- line drawing thickness cube: Cube ¬ NIL, -- the parent cube fancy: BOOL ¬ FALSE -- draw it fancy or simple? ]; G3dCubeDrawCube: Commander.CommandProc ~ { argv: CommanderOps.ArgumentVector ~ CommanderOps.Parse[cmd]; d: DrawData ~ NEW[DrawDataRec]; d.fancy ¬ argv.argc =2 AND Rope.Find[argv[1], "-Fancy", 0, FALSE] # -1; d.lineThickness ¬ Controls.NewControl["line",, d,, 10.0, 1.0, LineThickness]; d.tool ¬ G3dTool.MakeTool[ name: IF d.fancy THEN "A Fancy Volume Cube" ELSE "A Simple Volume Cube", extraButtons: LIST[ B["Pendant-Off", TogglePendant, d], B["Labels-Off", ToggleLabels, d]], graphicsHeight: 400, client: [draw: Draw, data: d]]; d.cube ¬ G3dOctree.NewCube[0.4, [-0.15, 0.0, 0.]]; }; LineThickness: Controls.ControlProc ~ { d: DrawData ~ NARROW[control.clientData]; IF control.mouse.button = right THEN G3dTool.Repaint[d.tool]; }; ToggleLabels: ClickProc ~ { d: DrawData ~ NARROW[clientData]; d.labels ¬ NOT d.labels; Controls.ButtonToggle[d.tool.outerData, d.labels, "Labels-On", "Labels-Off"]; IF mouseButton = blue THEN G3dTool.Repaint[d.tool]; }; TogglePendant: ClickProc ~ { d: DrawData ~ NARROW[clientData]; d.pendant ¬ NOT d.pendant; Controls.ButtonToggle[d.tool.outerData, d.pendant, "Pendant-On", "Pendant-Off"]; IF mouseButton = blue THEN G3dTool.Repaint[d.tool]; }; Draw: G3dTool.DrawProc ~ { d: DrawData ~ NARROW[clientData]; IF d.lineThickness.value # 1.0 THEN Imager.SetStrokeWidth[context, d.lineThickness.value]; IF d.fancy THEN G3dCubeDraw.FancyCube[context, d.cube, view, vp, d.labels] ELSE { pairs: OctantPairs ¬ G3dCubeDraw.TransformOctants[d.cube, view]; G3dCubeDraw.SimpleCubeFromPairs[context, pairs, d.cube]; IF d.labels THEN G3dCubeDraw.LabelOctants[context, pairs]; }; IF d.pendant THEN G3dDraw.Pendant[context, view, 0.07, 0.5, 0.35, ["r", "t", "f", "l", "b", "n"]]; }; ReadData: TYPE ~ REF ReadDataRec; ReadDataRec: TYPE ~ RECORD [ tool: G3dTool.Tool ¬ NIL, -- viewer for graphical display root: Cube ¬ NIL -- the parent cube ]; VolumeRead: Commander.CommandProc ~ { argv: CommanderOps.ArgumentVector ¬ CommanderOps.Parse[cmd]; IF argv.argc # 2 THEN RETURN[$Failure, "usage: VolumeRead "] ELSE { d: ReadData ~ NEW[ReadDataRec]; d.root ¬ G3dOctree.ReadCubesFromFile[argv[1]]; IF d.root = NIL THEN RETURN[$Failure, Rope.Cat["Can't read ", argv[1], "."]]; d.tool ¬ G3dTool.MakeTool[ name: Rope.Concat["Volume Read ", argv[1]], graphicsHeight: 400, client: [draw: ReadDrawProc, data: d]]; }; }; ReadDrawProc: G3dTool.DrawProc ~ { Action: PROC ~ { cubeProc: CubeProc ~ { G3dCubeDraw.SimpleCube[ context, cube, view, vp, TRUE, IF cube.terminal THEN solid ELSE dashed]; }; G3dOctree.Apply[d.root, cubeProc]; }; d: ReadData ~ NARROW[clientData]; Draw2d.DoWithBuffer[context, Action]; }; NeighborsData: TYPE ~ REF NeighborsDataRec; NeighborsDataRec: TYPE ~ RECORD [ tool: G3dTool.Tool, parent: Cube ¬ NIL, -- the parent cube new: Neighborhood, -- the moving cube old: Neighborhood -- where it last was ]; VolumeNeighbors: Commander.CommandProc ~ { d: NeighborsData ~ NEW[NeighborsDataRec]; G3dOctree.RecursivelySubdivide[d.parent, 2]; d.new ¬ G3dOctree.Move[d.new[c] ¬ G3dOctree.FirstTerminalKid[d.parent], c]; d.tool ¬ G3dTool.MakeTool[ name: "Volume Neighbors", extraButtons: LIST[ B["l",Nmov,d],B["r",Nmov,d],B["b",Nmov,d],B["t",Nmov,d],B["n",Nmov,d],B["f",Nmov,d]], graphicsHeight: 400, client: [draw: NeighborsDrawProc, data: d]]; }; NeighborsDrawProc: G3dTool.DrawProc ~ { Show: PROC [color: Imager.Color, n: Neighborhood] ~ { IF n[c] = NIL THEN RETURN; Imager.SetColor[context, color]; G3dCubeDraw.SimpleCube[context, n[c], view, vp, FALSE, solid]; G3dCubeDraw.LabelCube[context, n[c], c, view, vp]; }; d: NeighborsData ~ NARROW[clientData]; IF whatChanged = NIL THEN { G3dCubeDraw.RecursiveCubes[context, d.parent, view, vp, solid, FALSE]; G3dCubeDraw.LabelOctants[context, G3dCubeDraw.TransformOctants[d.parent, view]]; } ELSE Show[Imager.white, d.old]; Show[Imager.black, d.new]; }; NeighborsCamera: Controls.ControlProc ~ { d: NeighborsData ~ NARROW[clientData]; IF RespondNow[control] THEN G3dTool.Repaint[d.tool]; }; Nmov: ClickProc ~ { d: NeighborsData ~ NARROW[clientData]; direction: Direction ~ G3dOctree.DirectionFromRope[NARROW[parent, Viewer].name]; newer: Neighborhood ~ G3dOctree.Move[d.new[c], direction]; IF newer[c] = NIL THEN Flash["Can't move in that direction."] ELSE { d.old ¬ d.new; d.new ¬ newer; G3dTool.Repaint[d.tool]; }; }; AddDelData: TYPE ~ REF AddDelDataRec; AddDelDataRec: TYPE ~ RECORD [ tool: G3dTool.Tool ¬ NIL, -- parent viewer root: Cube ¬ NIL, -- the parent cube cube: Cube ¬ NIL -- the moving cube ]; VolumeAddDel: Commander.CommandProc ~ { L: PROC [r: ROPE] RETURNS [Controls.Button] ~ {RETURN[B[r, Amov, d]]}; d: AddDelData ~ NEW[AddDelDataRec]; d.root ¬ G3dOctree.NewCube[0.4]; G3dOctree.RecursivelySubdivide[d.root, 1]; d.cube ¬ G3dOctree.FirstTerminalKid[d.root]; d.tool ¬ G3dTool.MakeTool[ name: "Volume AddDel", extraButtons: LIST[L["L"], L["R"], L["B"], L["T"], L["N"], L["F"],B["Add", Add], B["Del", Del]], graphicsHeight: 400, client: [draw: AddDelDrawProc, data: d]]; }; AddDelDrawProc: G3dTool.DrawProc ~ { cubeProc: CubeProc ~ {G3dCubeDraw.SimpleCube[context, cube, view]}; d: AddDelData ~ NARROW[clientData]; G3dOctree.ApplyToTerminal[d.root, cubeProc]; G3dCubeDraw.SimpleCube[context, d.cube, view, vp, FALSE, solid]; G3dDraw.Pendant[context, view, .07, .7, .7, ["r", "t", "f", "l", "b", "n"]]; }; Amov: ClickProc ~ { d: AddDelData ~ NARROW[clientData]; direction: Direction ~ G3dOctree.DirectionFromRope[NARROW[parent, Viewer].name]; cube: Cube ~ G3dOctree.Neighbor[d.cube, direction]; IF cube = NIL THEN Flash["Can't move in that direction."] ELSE { d.cube ¬ cube; G3dTool.Repaint[d.tool]; }; }; GetFace: PROC [t: G3dTool.Tool] RETURNS [face: Face] ~ { Controls.TypescriptWrite[t.typescript, "Face: "]; face ¬ G3dOctree.FaceFromRope[Controls.TypescriptRead[t.typescript]]; }; Add: ClickProc ~ { d: AddDelData ~ NARROW[clientData]; face: Face ¬ GetFace[d.tool]; cube: Cube ¬ G3dOctree.AddCube[d.cube, face]; IF cube = NIL THEN Flash["No cube in that direction."] ELSE { d.cube ¬ cube; G3dTool.Repaint[d.tool]; }; }; Del: ClickProc ~ { d: AddDelData ~ NARROW[clientData]; face: Face ¬ GetFace[d.tool]; cube: Cube ¬ G3dOctree.FaceNeighbor[d.cube, face]; IF cube = NIL THEN Flash["No cube in that direction."] ELSE { G3dOctree.DeleteCube[cube]; G3dTool.Repaint[d.tool]; }; }; B: PROC [ name: ROPE ¬ NIL, proc: ClickProc ¬ NIL, data: REF ANY ¬ NIL, row, x, y, w, h: INTEGER ¬ 0, fork: BOOL ¬ TRUE, doc: ROPE ¬ NIL, guarded: BOOL ¬ FALSE, font: Imager.Font ¬ NIL, style: ATOM ¬ $BlackOnWhite] RETURNS [b: Controls.Button] ~ { b ¬ Controls.ClickButton[name, proc, data, row, x, y, w, h, fork, guarded, doc, font, style]; }; RespondNow: PROC [control: Control] RETURNS [BOOL] ~ { RETURN[control.mouse.button = right AND control.mouse.state # up]; }; Flash: PROC [message: ROPE] ~ { MessageWindow.Append[message, TRUE]; MessageWindow.Blink[]; }; G3dTool.Register["VolumeAddDel", VolumeAddDel, "add/delete a cube."]; G3dTool.Register["CubeDraw", G3dCubeDrawCube, "draw a cube [-fancy]."]; G3dTool.Register["VolumeNeighbors", VolumeNeighbors, "show cube's neighbors."]; G3dTool.Register["VolumeRead", VolumeRead, "VolumeRead ."]; END. φ G3dVolumeCmdsAImpl.mesa Copyright Σ 1985, 1992 by Xerox Corporation. All rights reserved. Bloomenthal, November 21, 1992 3:04 pm PST Cube Drawing Reading a Volume A Cube's Neighborhood Adding/Deleting a Cube Support Procedures Start Code Κ0•NewlineDelimiter –"cedarcode" style™™Jšœ Οeœ6™BJ™*J˜JšΟk œ–˜ŸJ˜—šΠblœžœž˜!Jšžœf˜mJ˜—šœž˜J˜Jšžœ ˜J˜Jšœžœ˜&Jšœžœ˜!Jšœ žœ˜#Jšœ žœ˜'Jšœžœ˜"—headšΟl ™ Jšœ žœžœ ˜"šœ žœžœ˜JšœžœΟc˜3Jšœ žœžœ‘ ˜,Jšœ žœžœ‘ ˜,Jšœžœ‘˜=Jšœžœ‘˜.Jšœ žœžœ‘˜7J˜J˜—šΟbœ˜*J˜J˜2J˜—Jšœžœ ˜&šžœžœžœ˜Jšœ?žœ˜FJ˜PJ˜—Jšžœ˜J˜J˜J˜—š£œ˜)Jšœžœ ˜&Jšžœžœ˜4J˜J˜—š£œ˜Jšœžœ ˜&Jšœ3žœ˜PJ˜:Jšžœ žœžœ'˜=šžœ˜J˜J˜J˜J˜—J˜——š ™Jšœ žœžœ˜'šœžœžœ˜Jšœžœ‘˜4Jšœžœ‘˜/Jšœžœ‘˜.J˜—J˜š’ œ˜'Jš £œžœžœžœžœ˜FJšœžœ˜#J˜ J˜*J˜,˜J˜JšœžœN˜`J˜J˜)—J˜—J˜š’œ˜$Jš£œ;˜CJšœžœ ˜#J˜,Jšœ2žœ ˜@J˜LJ˜J˜—š£œ˜Jšœžœ ˜#Jšœ3žœ˜PJ˜3Jšžœžœžœ'˜9šžœ˜J˜J˜J˜—J˜J˜—š£œžœžœ˜8J˜1J˜EJ˜J˜—š£œ˜Jšœžœ ˜#J˜J˜-Jšžœžœžœ$˜6šžœ˜J˜J˜J˜—J˜J˜—š£œ˜Jšœžœ ˜#J˜J˜2Jšžœžœžœ$˜6šžœ˜J˜J˜J˜—J˜——š ™š£œžœ˜ Jšœžœžœ˜Jšœžœ˜Jšœžœžœžœ˜Jšœžœ˜Jšœžœžœ˜Jšœžœžœ˜Jšœ žœžœ˜Jšœžœ˜Jšœžœ˜Jšžœ˜J˜J˜]J˜—J˜š£ œžœžœžœ˜6Jšžœžœ˜BJ˜J˜—š£œžœ žœ˜Jšœžœ˜$J˜J˜——š  ™ J˜EJ˜GJ˜OJ˜EJ˜—Jšžœ˜J˜—…—Ζ(μ