DIRECTORY Buttons, CedarProcess, CtBasic, Commander, CommanderOps, Controls, Convert, Draw2d, FileNames, FS, G3dBasic, G3dControl, G3dMatrix, G3dTool, Icons, Imager, ImagerBackdoor, ImagerFont, ImplicitSlice, MessageWindow, Real, Rope, SF, TEditSelection, TiogaMenuOps, VFonts, ViewerClasses, ViewerOps, ViewerTools; ImplicitSliceImpl: CEDAR PROGRAM IMPORTS Buttons, CedarProcess, CtBasic, Commander, CommanderOps, Controls, Convert, Draw2d, FileNames, FS, G3dControl, G3dMatrix, G3dTool, Icons, Imager, ImagerBackdoor, ImagerFont, MessageWindow, Real, Rope, TEditSelection, TiogaMenuOps, VFonts, ViewerOps, ViewerTools EXPORTS ImplicitSlice ~ BEGIN CommandProc: TYPE ~ Commander.CommandProc; ButtonList: TYPE ~ Controls.ButtonList; ClickProc: TYPE ~ Controls.ClickProc; Control: TYPE ~ Controls.Control; ControlList: TYPE ~ Controls.ControlList; SampleMap: TYPE ~ CtBasic.SampleMap; SampleMaps: TYPE ~ CtBasic.SampleMaps; DrawProc: TYPE ~ Draw2d.DrawProc; Pair: TYPE ~ G3dBasic.Pair; Triple: TYPE ~ G3dBasic.Triple; Slice: TYPE ~ G3dControl.Slice; Context: TYPE ~ Imager.Context; Function: TYPE ~ ImplicitSlice.Function; Pix: TYPE ~ ImplicitSlice.Pix; PixRep: TYPE ~ ImplicitSlice.PixRep; PixSequence: TYPE ~ ImplicitSlice.PixSequence; Tool: TYPE ~ ImplicitSlice.Tool; ToolRep: TYPE ~ ImplicitSlice.ToolRep; ROPE: TYPE ~ Rope.ROPE; Viewer: TYPE ~ ViewerClasses.Viewer; icon: Icons.IconFlavor _ Icons.NewIconFromFile["ImplicitSurfaces.icon", 0]; MakeTool: PUBLIC PROC [ toolName: ROPE, functions: LIST OF Function _ NIL, clientDraw: DrawProc _ NIL, clientData: REF ANY _ NIL, extraControls: ControlList _ NIL, extraButtons: ButtonList _ NIL] RETURNS [t: Tool] ~ { t _ NEW[ToolRep]; t.clientDraw _ clientDraw; t.clientData _ clientData; t.slice _ G3dControl.InitSlice[proc: SliceControl, data: t]; t.slice.phi.value _ 90.0; FOR b: ButtonList _ extraButtons, b.rest WHILE b # NIL DO b.first.row _ 1; ENDLOOP; extraButtons _ CONS[Controls.ClickButton["Help", Help, t, 0], extraButtons]; extraButtons _ CONS[Controls.ClickButton["IP Out", IPOut, t, 0], extraButtons]; extraButtons _ CONS[Controls.ClickButton["Display-Ops", DisplayOps, t, 0], extraButtons]; extraButtons _ CONS[Controls.TextButton["MoveSlice: ","-.03", CheckValue, t, 0], extraButtons]; extraButtons _ CONS[Controls.TextButton["H: ", "80 ", CheckValue, t, 0], extraButtons]; extraButtons _ CONS[Controls.TextButton["W: ", "80 ", CheckValue, t, 0], extraButtons]; extraButtons _ CONS[Controls.ClickButton["Name", NamePix, t, 0], extraButtons]; extraButtons _ CONS[Controls.ClickButton["STOP", Stop, t, 0], extraButtons]; extraButtons _ CONS[Controls.ClickButton["StartAndMove", StartAndMove, t, 0], extraButtons]; extraButtons _ CONS[Controls.ClickButton["Start", Start, t, 0], extraButtons]; extraButtons _ CONS[Controls.ClickButton["Mode: Slice", ToggleMode, t, 0], extraButtons]; extraControls _ CONS[t.slice.size, extraControls]; extraControls _ CONS[t.slice.theta, extraControls]; extraControls _ CONS[t.slice.phi, extraControls]; extraControls _ CONS[t.slice.z, extraControls]; extraControls _ CONS[t.slice.y, extraControls]; extraControls _ CONS[t.slice.x, extraControls]; FOR f: LIST OF Function _ functions, f.rest WHILE f # NIL DO AddPix[t, f.first]; ENDLOOP; t.renderTool _ G3dTool.MakeTool[ name: toolName, ops: [TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE], extraButtons: extraButtons, extraControls: extraControls, controlSizes: [15, 200, 60, 20, 60, 150, 150], arcBallSize: 80, nViews: 3, client: [mouse: Mouse3d, destroy: Destroy, draw: Draw, data: t], noOpen: TRUE]; t.viewer2d _ Controls.OuterViewer[mouse: Mouse2d, clientData: t, destroy: Destroy]; t.renderTool.outer.icon _ icon; t.typescript _ t.renderTool.typescript; t.valueViewer _ ViewerOps.CreateViewer[ flavor: $ValueViewer, paint: FALSE, info: [data: t, scrollable: FALSE, wx: 510, wy: 16, ww: 80, wh: 80, border: FALSE, parent: t.renderTool.outer]]; ViewerOps.AddProp[t.valueViewer, $CreatedInOuterViewer, $True]; ViewerOps.OpenIcon[t.renderTool.outer]; }; Destroy: Controls.DestroyProc ~ {NARROW[clientData, Tool].stop _ TRUE}; SliceControl: Controls.ControlProc ~ { t: Tool _ NARROW[control.clientData]; t.pixPicked _ NIL; G3dControl.UpdateSlice[t.slice]; IF control.whatChanged = $TypedIn OR control.mouse.button = right THEN Repaint[t, $Slice]; }; Mouse3d: Controls.MouseProc ~ { t: Tool _ NARROW[clientData]; IF mouse.controlKey THEN { x: G3dMatrix.Matrix _ G3dTool.GetView[viewer, t.renderTool].camera.matrix; t.pixPicked _ t.pixes[0]; t.point _ SELECT t.mode FROM slice => G3dMatrix.TripleFromScreenAndPlane[[mouse.pos.x, mouse.pos.y], t.slice.plane, x], ENDCASE => t.renderTool.sprite; IF t.pixPicked # NIL AND t.pixPicked.valueProc # NIL THEN { t.value _ t.pixPicked.valueProc[t.point, t.clientData]; ViewerOps.PaintViewer[t.valueViewer, client, FALSE]; }; }; }; Mouse2d: Controls.MouseProc ~ { t: Tool ~ NARROW[clientData]; IF mouse.state = up AND mouse.pos.y <= t.ySize THEN FOR n: NAT IN [0..t.pixes.length) DO t.pixPicked _ t.pixes[n]; IF mouse.pos.x IN [t.pixPicked.box.min.f..t.pixPicked.box.max.f] THEN { t.point _ GetPixPoint[t, t.pixPicked, mouse.pos.x, mouse.pos.y]; Repaint[t, $PixPicked]; EXIT; }; ENDLOOP; }; Repaint: PUBLIC PROC [tool: Tool, whatChanged: REF ANY _ NIL] ~ { G3dTool.Repaint[tool.renderTool, whatChanged]; }; PaintValueViewer: ViewerClasses.PaintProc ~ { Action: PROC ~ { IF whatChanged = NIL THEN Draw2d.Circle[context, [size, size], size]; Draw2d.Circle[context, [size, size], radius, t.value > 0.0]; }; t: Tool _ NARROW[self.data]; size: INTEGER _ self.ww/2; radius: REAL _ ABS[t.value]*self.ww; Draw2d.DoWithBuffer[context, Action]; }; Draw: DrawProc ~ { t: Tool ~ NARROW[data]; DiagramPix: PROC [pix: Pix] ~ { IF v.index = 0 AND pix # NIL AND pix.diagramProc # NIL THEN pix.diagramProc[context, t.point, t.clientData, whatChanged, viewer]; }; DrawSlice: PROC ~ { IF t.mode = slice AND t.showSlice THEN G3dControl.DrawSlice[context, t.slice, v.camera.matrix, vp]; }; v: G3dTool.View _ G3dTool.GetView[viewer, t.renderTool]; vp: G3dMatrix.Viewport _ G3dView.GetViewport[viewer]; SELECT whatChanged FROM $Clear => Draw2d.Clear[context]; $Slice => G3dTool.Restore[context, v]; $FinishingTouches => {DiagramPix[t.pixPicked]; DrawSlice[]}; ENDCASE => IF t.clientDraw # NIL THEN t.clientDraw[context, t.clientData, whatChanged, viewer]; IF t.cdContext # NIL THEN context _ t.cdContext; }; DisplayOps: ClickProc ~ { t: Tool _ NARROW[clientData]; SELECT Controls.PopUpRequest[["Display Options"], LIST[ Controls.BoolRequest[t.showSlice, "Show Slice"]]] FROM 1 => t.showSlice _ NOT t.showSlice; ENDCASE => RETURN; IF Controls.GetPopUpButton[] = right THEN Repaint[t]; }; ToggleMode: ClickProc ~ { t: Tool _ NARROW[clientData]; IF t.mode = slice THEN {t.mode _ sprite; Buttons.ReLabel[parent, "Mode: Sprite"]} ELSE {t.mode _ slice; Buttons.ReLabel[parent, "Mode: Slice"]}; t.renderTool.drawSprite _ t.mode = sprite; Repaint[t]; }; doc: ROPE _ FileNames.StripVersionNumber[FS.FileInfo["ImplicitSurfacesDoc.tioga"].fullFName]; Help: ClickProc ~ { v: Viewer _ TiogaMenuOps.Open[doc,, right]; TEditSelection.FindRope[v, "ImplicitSlice Buttons and Controls"]; }; IPOut: ClickProc ~ { t: Tool _ NARROW[clientData]; Draw2d.IPOut[Controls.TypescriptReadFileName[t.typescript], Draw, t]; }; NamePix: ClickProc ~ {SetUpPix[NARROW[clientData], 0.5, FALSE, TRUE]}; SetParameters: PROC [t: Tool] ~ { FOR b: LIST OF Controls.Button _ t.renderTool.buttons, b.rest WHILE b # NIL DO E: PROC [r: ROPE] RETURNS [BOOL] ~ {RETURN[Rope.Equal[b.first.name, r, FALSE]]}; N: PROC [o: REAL] RETURNS [i: REAL] ~ { r: ROPE _ ViewerTools.GetContents[b.first.textViewer]; i _ Convert.RealFromRope[r ! Convert.Error => {Blink["Bad value"]; i _ o; CONTINUE}]; }; SELECT TRUE FROM E["MoveSlice: "] => t.moveSlice _ N[t.moveSlice]; E["W: "] => t.xSize _ Real.Round[N[t.xSize]]; E["H: "] => t.ySize _ Real.Round[N[t.ySize]]; ENDCASE; ENDLOOP; ResizePixes[t]; }; CheckValue: ClickProc ~ { button: Controls.Button _ NARROW[ViewerOps.FetchProp[parent, $ButtonText]]; IF button # NIL THEN { r: ROPE _ ViewerTools.GetContents[button.textViewer]; [] _ Convert.RealFromRope[r ! Convert.Error => {Blink["Bad value"]; CONTINUE}]; }; }; Stop: ClickProc ~ { t: Tool _ NARROW[clientData]; t.stop _ TRUE; Controls.TypescriptWrite[t.typescript, " . . . aborted.\n"]; }; Start: ClickProc ~ {StartShade[NARROW[clientData], Shade]}; StartAndMove: ClickProc ~ {StartShade[NARROW[clientData], ShadeAndMoveSlice]}; StartShade: PROC [t: Tool, proc: CedarProcess.ForkableProc] ~ { t.stop _ FALSE; SetParameters[t]; [] _ CedarProcess.Fork[proc, t, [background, TRUE]]; t.stop _ FALSE; }; Shade: CedarProcess.ForkableProc ~ { t: Tool _ NARROW[data]; SetUpPix[t, 0.0, TRUE, TRUE]; FOR y: NAT IN [1..t.ySize-1) DO FOR x: NAT IN [1..t.xSize-1) DO t.point _ GetPixPoint[t, t.pixes[0], x, y]; FOR n: NAT IN [0..t.pixes.length) DO pix: Pix _ t.pixes[n]; value: REAL _ pix.valueProc[t.point, t.clientData]; pVal: CARDINAL _ Real.Round[MIN[255.0, MAX[0., 255.0*value]]]; xx: NAT _ x+pix.box.min.f; yy: NAT _ y+pix.box.min.s; IF t.stop THEN RETURN; SELECT pix.maps.bpp FROM 8 => CtBasic.PutBWPixel[pix.maps[0].map, xx, yy, pVal]; 24 => CtBasic.PutRGBPixel[pix.maps, xx, yy, [pVal, pVal, pVal]]; ENDCASE; ENDLOOP; ENDLOOP; ENDLOOP; }; ShadeAndMoveSlice: CedarProcess.ForkableProc ~ { t: Tool _ NARROW[data]; box: SF.Box _ t.cdMaps.box; FOR y: NAT _ box.min.s, y+t.ySize WHILE y < box.max.s DO FOR x: NAT _ box.min.f, x+t.xSize WHILE x < box.max.f DO FOR n: NAT IN [0..t.pixes.length) DO IF t.stop THEN RETURN; t.pixes[n].maps _ CtBasic.CopyOfMaps[t.cdMaps, x, y, t.xSize, t.ySize]; ENDLOOP; [] _ Shade[t]; G3dControl.MoveSliceInZ[t.slice, t.moveSlice]; Repaint[t]; ENDLOOP; ENDLOOP; }; ImagerShade: CedarProcess.ForkableProc ~ { t: Tool _ NARROW[data]; t.cdContext _ CtBasic.InitCd[gray]; Repaint[t, $Clear]; [] _ Shade[t]; t.cdContext _ CtBasic.InitCd[smooth]; Repaint[t]; t.cdContext _ NIL; }; AddPix: PROC [t: Tool, f: Function] ~ { xStart: NAT _ IF t.pixes # NIL THEN t.xSize*t.pixes.length ELSE 0; pix: Pix _ NEW[PixRep]; new: REF PixSequence _ NEW[PixSequence[IF t.pixes # NIL THEN t.pixes.length+1 ELSE 1]]; FOR n: NAT IN [0..new.length-1) DO new[n] _ t.pixes[n]; ENDLOOP; t.pixes _ new; pix.name _ f.name; pix.diagramProc _ f.diagramProc; pix.valueProc _ f.valueProc; SetPixSize[pix, xStart, 0, t.xSize, t.ySize, t.cdMaps]; t.pixes[t.pixes.length-1] _ pix; }; SetPixSize: PROC [pix: Pix, x, y, w, h: NAT, cd: SampleMaps] ~ { pix.maps _ CtBasic.CopyOfMaps[cd, x, y, w, h]; pix.box _ pix.maps.box; pix.context _ CtBasic.InitCd[smooth, TRUE, FALSE, FALSE]; CtBasic.TransformContextToMap[ pix.context, SELECT pix.maps.bpp FROM 8 => pix.maps[0].map ENDCASE => pix.maps[1].map]; pix.start _ ImagerFont.RopeEscapement[ImagerBackdoor.GetFont[pix.context], pix.name]; pix.start _ [-0.5*pix.start.x, -0.9]; }; ResizePixes: PROC [t: Tool] ~ { IF t.pixes # NIL THEN FOR n: NAT IN [0..t.pixes.length) DO SetPixSize[t.pixes[n], n*t.xSize, 0, t.xSize, t.ySize, t.cdMaps]; ENDLOOP; }; GetPixPoint: PROC [t: Tool, pix: Pix, x, y: NAT] RETURNS [Triple] ~ { map: SampleMap _ IF pix.maps.bpp = 8 THEN pix.maps[0].map ELSE pix.maps[1].map; realPair: CtBasic.RealPair _ CtBasic.PairFromMapCoords[x, y, map]; RETURN[G3dMatrix.TransformPair[[realPair.x, realPair.y], t.slice.matrix]]; }; SetUpPix: PROC [t: Tool, gray: REAL, clear, name: BOOL] ~ { FOR n: NAT IN [0..t.pixes.length) DO pix: Pix _ t.pixes[n]; Imager.SetGray[pix.context, gray]; Imager.SetStrokeWidth[pix.context, 0.02]; IF clear THEN CtBasic.FillMaps[pix.maps, 100, 100, 100, 100]; IF name THEN Draw2d.Label[pix.context, pix.start, pix.name]; ENDLOOP; }; Blink: PROC [rope: ROPE] ~ { MessageWindow.Append[rope, TRUE]; MessageWindow.Blink[]; }; PixelValueFromValue: PROC [value: REAL] RETURNS [CARDINAL] ~ { RETURN[Real.Round[MIN[255.0, MAX[0.0, 255.0*value]]]]; }; Registration: TYPE ~ RECORD [ name: ROPE, -- name of option command: CommandProc, -- proc to be called doc: ROPE -- documentation of option ]; registry: LIST OF Registration _ NIL; font: VFonts.Font ~ VFonts.EstablishFont["Tioga", 10]; tabWidth: INT _ 2*VFonts.StringWidth["\t"]; -- VFonts says 12; but should be 24 toolOptions: ROPE _ NIL; toolUsage: ROPE _ "ImplicitSlice