<<>> <> <> <> DIRECTORY Atom, BasicTime, CedarProcess, Commander, CommanderOps, Controls, Convert, Draw2d, FileNames, FS, G2dBasic, G2dVector, G3dBasic, G3dCubeDraw, G3dDraw, G3dMatrix, G3dOctree, G3dRayCube, G3dRayTrace, G3dRayTraceTool, G3dRender, G3dShade, G3dShape, G3dTool, G3dVector, G3dView, Icons, Imager, ImplicitDefs, ImplicitOctree, ImplicitDraw, ImplicitPolygons, ImplicitPoints, ImplicitRayTrace, ImplicitSurface, IO, MessageWindow, PFS, ProcessProps, Rope, TEditSelection, TiogaMenuOps, VFonts, ViewerClasses, ViewerOps; ImplicitOctreeImpl: CEDAR PROGRAM IMPORTS Atom, BasicTime, CedarProcess, Commander, CommanderOps, Controls, Convert, Draw2d, FileNames, G2dVector, G3dCubeDraw, G3dDraw, G3dMatrix, G3dOctree, G3dShade, G3dRayCube, G3dRayTrace, G3dRayTraceTool, G3dShape, G3dTool, G3dVector, Icons, Imager, ImplicitDraw, ImplicitPolygons, ImplicitPoints, ImplicitRayTrace, ImplicitSurface, IO, MessageWindow, PFS, ProcessProps, Rope, TEditSelection, TiogaMenuOps, VFonts, ViewerOps EXPORTS ImplicitOctree ~ BEGIN <> ForkableProc: TYPE ~ CedarProcess.ForkableProc; CommandProc: TYPE ~ Commander.CommandProc; ButtonList: TYPE ~ Controls.ButtonList; ClickProc: TYPE ~ Controls.ClickProc; Triple: TYPE ~ G3dBasic.Triple; Matrix: TYPE ~ G3dMatrix.Matrix; Cube: TYPE ~ G3dOctree.Cube; RayData: TYPE ~ G3dRayTrace.RayData; DistanceMode: TYPE ~ ImplicitDefs.DistanceMode; EdgeMode: TYPE ~ ImplicitDefs.EdgeMode; StartProc: TYPE ~ ImplicitDefs.StartProc; Tool: TYPE ~ ImplicitOctree.Tool; ToolRep: TYPE ~ ImplicitOctree.ToolRep; ROPE: TYPE ~ Rope.ROPE; Viewer: TYPE ~ ViewerClasses.Viewer; <> icon: Icons.IconFlavor ¬ Icons.NewIconFromFile["ImplicitSurfaces.icon", 0]; gtool: Tool; MakeTool: PUBLIC PROC [ name: ROPE, valueProc: ImplicitDefs.ValueProc, ops: G3dTool.Operations ¬ G3dTool.allOps, extraButtons: ButtonList ¬ NIL, extraControls: Controls.ControlList ¬ NIL, controlSizes: Controls.ControlSizes ¬ [], useArcBalls: BOOL ¬ TRUE, arcBallSize: INT ¬ 136, client: G3dTool.Client ¬ [], graphicsHeight: INT ¬ 475, background: Triple ¬ [0.3, 0.3, 1.0], noOpen: BOOL ¬ FALSE, startProc: StartProc ¬ NIL, cubeOkProc: ImplicitDefs.CubeOkProc ¬ NIL, vertexOkProc: ImplicitDefs.VertexOkProc ¬ NIL, polygonOkProc: ImplicitDefs.PolygonOkProc ¬ NIL, normalProc: ImplicitDefs.NormalProc ¬ NIL, colorProc: ImplicitDefs.ColorProc ¬ NIL, textureProc: ImplicitDefs.TextureProc ¬ NIL, rayProc: G3dRayTrace.RayProc ¬ NIL, docProc: ImplicitDefs.DocProc ¬ NIL, camera: G3dView.CameraRep ¬ [[0.0, 2.0, 0.0], [], 1.0, 60.0], nViews: NAT ¬ 1, toolSettings: ToolRep ¬ []] RETURNS [t: Tool] ~ { AddButton: PROC [name: ROPE, proc: ClickProc, guarded: BOOL ¬ FALSE] ~ { extraButtons ¬ CONS[Controls.ClickButton[name, proc, t, 1,,,,,, guarded], extraButtons]; }; cmd: Commander.Handle ¬ NARROW[ProcessProps.GetProp[$CommanderHandle]]; ref: REF ANY ¬ CommanderOps.GetProp[cmd, $Tool]; calledByMakeSurface: BOOL ¬ ref # NIL; showTool: BOOL ¬ CommanderOps.GetProp[cmd, $ShowTool] # NIL; t ¬ IF calledByMakeSurface THEN NARROW[ref] ELSE NEW[ToolRep ¬ toolSettings]; IF NOT calledByMakeSurface THEN { -- call originated with ImplicitOctree command FOR l: ButtonList ¬ extraButtons, l.rest WHILE l # NIL DO l.first.row ¬ MAX[2, l.first.row]; ENDLOOP; <> AddButton["Octree", OctreeButton]; AddButton["HLE", HLEButton]; AddButton["RayTrace", RayTraceButton]; }; t.startProc ¬ startProc; IF valueProc # NIL THEN t.valueProc ¬ valueProc; IF cubeOkProc # NIL THEN t.cubeOkProc ¬ cubeOkProc; IF vertexOkProc # NIL THEN t.vertexOkProc ¬ vertexOkProc; IF polygonOkProc # NIL THEN t.polygonOkProc ¬ polygonOkProc; IF normalProc # NIL THEN t.normalProc ¬ normalProc; IF textureProc # NIL THEN t.textureProc ¬ textureProc; IF colorProc # NIL THEN t.colorProc ¬ colorProc; t.rayData ¬ NEW[G3dRayTrace.RayDataRep]; IF rayProc # NIL THEN t.rayProc ¬ rayProc; t.rayData.clientData ¬ t; t.rayData.finishProc ¬ RayTraceFinish; IF docProc # NIL THEN t.docProc ¬ docProc; t.client ¬ client; gtool ¬ t; IF NOT calledByMakeSurface OR showTool THEN { t.tool3d ¬ G3dTool.MakeTool[ name: name, nViews: nViews, ops: ops, extraButtons: extraButtons, extraControls: extraControls, controlSizes: controlSizes, client: [data: t, draw: Draw, mouse: Mouse, camera: Camera, animate: Animate, stop: Stop, destroy: Destroy, change: Change], useArcBalls: useArcBalls, arcBallSize: arcBallSize, graphicsHeight: graphicsHeight, background: background, icon: icon, camera: camera]; IF toolSettings = [] THEN SetToolFromLog[t, name]; }; }; Camera: Controls.ControlProc ~ { tool: Tool ¬ NARROW[clientData]; IF tool.client.camera # NIL THEN tool.client.camera[control, tool.client.data]; }; Change: G3dTool.ChangeProc ~ { tool: Tool ¬ NARROW[clientData]; IF tool.client.change # NIL THEN tool.client.change[lastTool, activeTool, tool.client.data]; }; Destroy: Controls.DestroyProc ~ { tool: Tool ¬ NARROW[clientData]; tool.destroyed ¬ TRUE; IF tool.client.destroy # NIL THEN tool.client.destroy[viewer, reason, tool.client.data]; }; Mouse: Controls.MouseProc ~ { m: G2dBasic.Pair ¬ [mouse.pos.x, mouse.pos.y]; nx, ny: G2dBasic.NearSegment; tool: Tool ¬ NARROW[clientData]; view: Matrix ¬ G3dTool.GetView[NIL, tool.tool3d].camera.matrix; r: RayData ¬ tool.rayData; p: ARRAY[0..4) OF G2dBasic.Pair; t: ARRAY[0..4) OF Triple; [t[0], t[1], t[2], t[3]] ¬ G3dRayTrace.RayImageScreenCorners[r]; FOR n: NAT IN [0..4) DO p[n] ¬ G3dMatrix.TransformD[t[n], view]; ENDLOOP; nx ¬ G2dVector.NearestToSegment[p[0], p[1], m]; ny ¬ G2dVector.NearestToSegment[p[1], p[2], m]; MessageWindow.Append[IO.PutFR["pixel (%g, %g)", IO.real[r.x+nx.w0*r.w], IO.real[r.y+ny.w0*r.h]], TRUE]; IF tool.client.mouse # NIL THEN tool.client.mouse[mouse, viewer, tool.client.data]; }; doc: ROPE ¬ "/PCedar/Documentation/ImplicitSurfacesDoc.tioga"; HelpButton: ClickProc ~ { v: Viewer ¬ TiogaMenuOps.Open[doc,, right]; TEditSelection.FindRope[v, "Buttons and Controls"]; }; <> ToolBusy: PUBLIC PROC [tool: Tool] RETURNS [BOOL] ~ { RETURN[G3dTool.ToolBusy[tool.tool3d]]; }; MaybeFork: PUBLIC PROC [tool: Tool, proc: ForkableProc] RETURNS [forked: BOOL] ~ { RETURN[G3dTool.MaybeFork[tool.tool3d, proc, tool]]; }; Stop: G3dTool.StopProc ~ {StopTool[NARROW[clientData], reason]}; StopTool: PUBLIC PROC [tool: Tool, reason: ROPE ¬ NIL, waitTilAborted: BOOL ¬ FALSE] ~ { G3dTool.Stop[tool.tool3d, reason, waitTilAborted]; IF tool.client.stop # NIL THEN tool.client.stop[tool.client.data, reason]; }; <> radius: REAL ¬ 0.002; trick, reset: BOOL ¬ FALSE; type: Draw2d.DrawType ¬ solid; Repaint: PUBLIC PROC [tool: Tool, whatChanged: REF ANY ¬ NIL] ~ { G3dTool.Repaint[tool.tool3d, whatChanged, IF tool.drawOctree THEN single ELSE default]; }; Draw: G3dTool.DrawProc ~ { DrawClient: PROC ~ { IF t.client.draw # NIL THEN t.client.draw[context, viewer, whatChanged, view, vp, v, tool, t.client.data]; }; DrawOctree: PROC ~ { Inner: G3dOctree.CubeProc ~ { IF ImplicitPoints.IsCrossed[cube ! ImplicitPoints.ValueNotSet => CONTINUE] THEN G3dCubeDraw.SimpleCube[context, cube, view, vp, FALSE, solid]; }; IF whatChanged = $IPOut THEN Imager.SetGray[context, .65]; IF t.octree # NIL THEN G3dOctree.ApplyToTerminal[t.octree.root, Inner]; Imager.SetGray[context, 1.0]; }; DrawRoots: PROC ~ { Imager.SetStrokeWidth[context, 1.5]; IF t.roots # NIL THEN FOR n: NAT IN [0..t.roots.length) DO G3dCubeDraw.SimpleCube[context, t.roots[n], view, vp,, dashed]; ENDLOOP; }; DrawAge: PROC ~ { IF t.cubes # NIL THEN { dgray: REAL ~ 1.0/REAL[2+t.cubes.length]; Imager.SetStrokeWidth[context, 4.0]; G3dCubeDraw.SimpleCube[context, t.cubes[0], view, vp,, dashed]; Imager.SetStrokeWidth[context, 1.5]; FOR n: NAT IN [1..t.cubes.length) DO gray: REAL ¬ 1.0-0.75*REAL[n]/REAL[t.cubes.length]; Imager.SetGray[context, gray]; G3dCubeDraw.SimpleCube[context, t.cubes[n], view, vp,, solid]; ENDLOOP; }; }; DrawPlayback: PROC ~ { A: ImplicitPolygons.PolygonProc ~{ImplicitDraw.DrawPolygon[context, t.surface, polygon]}; inv: Matrix ¬ G3dMatrix.Invert[view]; IF t.cubes # NIL THEN FOR n: NAT IN [0..t.cubes.length) DO G3dCubeDraw.SimpleCube[context, t.cubes[n], view, vp]; ENDLOOP; IF t.tool3d.shapes # NIL AND t.tool3d.shapes[0].vertices # NIL THEN FOR n: NAT IN [0..t.tool3d.shapes[0].vertices.length) DO pt: Triple ¬ t.tool3d.shapes[0].vertices[n].point; r: REAL ¬ G3dDraw.ScreenRadiusFromSphere[[pt, radius], view, inv, vp]; Draw2d.Circle[context, G3dMatrix.TransformD[pt, view], r, TRUE]; ENDLOOP; ImplicitPolygons.ApplyToSurfacePolygons[t.surface, A]; }; t: Tool ¬ NARROW[clientData]; IF v # NIL AND v.index = 0 THEN SELECT whatChanged FROM NIL, $IPOut, $NoClear, $Camera, $Scene => { ImplicitPoints.SetVertexScreenCoordsInvalid[t.surface]; IF t.drawOctree THEN DrawOctree[]; IF t.drawOctree AND t.drawRoots THEN Imager.SetStrokeWidth[context, 0.75]; IF t.drawAge THEN DrawAge[]; IF t.drawRoots THEN DrawRoots[]; DrawClient[]; IF t.showRayScreen THEN { G3dRayTrace.DrawRayImageScreen[context, t.rayData, view, vp]; IF t.rayData.lights # NIL THEN FOR n: NAT IN [0..t.rayData.lights.length) DO G3dDraw.Vector[context, t.rayData.eyePoint, t.rayData.lights[n].direction, view, vp, IO.PutFR1["LVec%g", IO.int[n]]]; ENDLOOP; }; }; $Clear => Draw2d.Clear[context]; $Client => {Draw2d.Clear[context]; DrawClient[]}; $HLE=> G3dDraw.Segment[context, t.hleSegment.p0, t.hleSegment.p1, view, vp]; $HLEOctree => {t.context ¬ context; [] ¬ MaybeFork[t, HLEDrawOctree]}; $NewRay => IF t.showRays THEN G3dRayTrace.DrawRayTip[context, t.rayData, view, vp]; $Playback => DrawPlayback[]; $NewTriangle => { tri: ImplicitOctree.Triangle ¬ t.currentTriangle; G3dDraw.SetColor[context, [0.0, 0.7, 0.7]]; G3dDraw.Triangle[context, tri.p1, tri.p2, tri.p3, view, vp]; }; ENDCASE => ImplicitDraw.DiagramProgress[context, t.surface, whatChanged, IF t.currentCube # NIL THEN t.currentCube.refAny ELSE NIL, view, vp, t.currentCube, t.drawOctree, TRUE, t.drawRoots] ELSE SELECT whatChanged FROM NIL, $IPOut, $NoClear, $Camera, $Scene, $Client => DrawClient[]; ENDCASE; }; HLEDrawOctree: ForkableProc ~ { t: Tool ¬ NARROW[data]; v: G3dTool.View ¬ G3dTool.GetView[NIL, t.tool3d]; G3dCubeDraw.HLEOctree[t.context, t.octree.root, v.camera.matrix, v.viewport]; }; <> RayTraceButton: ClickProc ~ { t: Tool ¬ NARROW[clientData]; G3dRayTraceTool.RayTraceOptions[t.rayData, t.tool3d.typescript, DoRayTrace, t]; IF Controls.GetPopUpButton[] = right THEN Repaint[t]; }; RayTraceFinish: G3dRayTrace.ClientProc ~ { t: Tool ¬ NARROW[clientData]; TSWrite[t, IO.PutFR1["Ray tracing finished at %g\n", IO.rope[Convert.RopeFromTime[BasicTime.Now[]]]]]; G3dTool.Finish[t.tool3d, "raytracing done"]; }; DoRayTrace: PROC [clientData: REF ANY] ~ {RayTrace[NARROW[clientData]]}; RayTrace: PUBLIC PROC [tool: Tool] ~ { IF ToolBusy[tool] THEN TSWrite[tool, "Tool is busy!\n"] ELSE { IF tool.octree = NIL THEN TSWrite[tool, "First, need octree.\n"] ELSE { TSWrite[tool, IO.PutFR1["Ray tracing begun at %g\n", IO.rope[Convert.RopeFromTime[BasicTime.Now[]]]]]; G3dRayTrace.StartRayTracing[tool.rayData]; tool.tool3d.process ¬ tool.rayData.process; }; }; }; ImplicitRayTraceProc: G3dRayTrace.RayProc ~ { IntersectOctree: PROC [r:G3dBasic.Ray, o:G3dOctree.Octree] RETURNS [G3dRayTrace.RGB] ~ { i: G3dOctree.Intersection ¬ G3dRayCube.IntersectRayWithCube[r, o.root]; RETURN[IF i.type = empty THEN [0.0, 0.0, 0.0] ELSE [1.0, 1.0, 1.0]]; }; t: Tool ¬ NARROW[clientData]; r: RayData ¬ t.rayData; IF r.nextPixel.x = r.x THEN MessageWindow.Append[IO.PutFR1["Starting line %g", IO.int[r.nextPixel.y]], TRUE]; IF t.showRays THEN Repaint[t, $NewRay]; SELECT TRUE FROM r.traceOctree => RETURN[IntersectOctree[ray, t.octree]]; t.rayProc # NIL => RETURN[t.rayProc[ray, t.client.data]]; t.valueProc = NIL => RETURN[IntersectOctree[ray, t.octree]]; ENDCASE => { s: ImplicitRayTrace.SurfacePoint ¬ ImplicitRayTrace.RayAtSurface[ray, t.octree, t.valueProc, t.threshold,, t.client.data]; SELECT TRUE FROM s.point = [] => rgb ¬ [0.0, 0.0, 0.0]; r.noShading => rgb ¬ [1.0, 1.0, 1.0]; ENDCASE => { intensity: REAL ¬ G3dShade.TotalSurfaceIntensity[s.normal, r.eyeView, r.lights, r.portionSpecular]; rgb ¬ [intensity, intensity, intensity]; }; }; }; <> Animate: G3dTool.AnimateProc ~ { ENABLE ImplicitSurface.NoSurfacePoint => CONTINUE; t: Tool ¬ NARROW[clientData]; <> <<1 => t.drawOptions.client ¬ NOT t.drawOptions.client;>> <<2 => {>> <> <> <> <> <> <> <<};>> <<3 => t.drawOptions.polygons ¬ NOT t.drawOptions.polygons;>> <<4 => {>> <> <> <> <<};>> <<5 => t.drawOptions.vertices ¬ NOT t.drawOptions.vertices;>> <<6 => t.drawOptions.labels ¬ NOT t.drawOptions.labels;>> <<7 => t.drawOptions.normals ¬ NOT t.drawOptions.normals;>> <<8 => t.drawOptions.dimFurtherLines ¬ NOT t.drawOptions.dimFurtherLines;>> <<9 => t.drawOptions.taperedLines ¬ NOT t.drawOptions.taperedLines;>> <<10 => t.drawOptions.pendant ¬ NOT t.drawOptions.pendant;>> <<11 => {Repaint[t, $NoClear]; RETURN};>> <<12 =>>> < ", t.tool3d.frameSize];>> <<13 => t.drawOctree ¬ NOT t.drawOctree;>> <<14 => t.directionSelect ¬ SELECT Controls.PopUpRequest[["Octree Display Mode"], LIST[>> <<["x","Show just x"], ["y","Show just y"], ["z","Show just z"], ["xy","Show just xy"],>> <<["xz","Show just xz"], ["yz","Show just yz"], ["xyz","Show all"]]] FROM>> <<1=>x, 2=>y, 3=>z, 4=>xy, 5=>xz, 6=>yz, 7=>xyz, ENDCASE=>t.directionSelect;>> <<15 => t.drawAge ¬ NOT t.drawAge;>> <<16 => t.drawRoots ¬ NOT t.drawRoots;>> <<17 => {Repaint[t, $Playback]; Repaint[t]; RETURN};>> <<18 => t.showRayScreen ¬ NOT t.showRayScreen;>> <<19 => t.showRays ¬ NOT t.showRays;>> <<20 =>>> <> <> <> < RETURN;>> <> <<};>> <<>> <<>>