<> <> <> <> <<>> DIRECTORY Atom, BufferedRefresh, CodeTimer, CoordSys, SVGraphics, DisplayListToTree, Feedback, GList, Imager, ImagerPath, ImagerTransformation, Matrix3d, Preprocess3d, PriorityQueue, Real, Rope, SV2d, SV3d, SVAssembly, SVBasicTypes, SVBoundBox, SVCaret, SVDraw3d, SVFiles, SVImage, SVInterfaceTypes, SVModelTypes, SVRayTypes, SVRefresh, SVScene, SVSceneTypes, SVSelect, SVSelections, SVUtility; SVRefreshImpl: CEDAR PROGRAM IMPORTS Atom, BufferedRefresh, CodeTimer, CoordSys, SVGraphics, DisplayListToTree, Feedback, GList, Imager, ImagerTransformation, Matrix3d, Preprocess3d, PriorityQueue, Rope, SVAssembly, SVBoundBox, SVCaret, SVDraw3d, SVFiles, SVImage, SVScene, SVSelect, SVSelections, SVUtility EXPORTS SVRefresh = BEGIN ArtworkToolData: TYPE = SVInterfaceTypes.ArtworkToolData; Slice: TYPE = SVSceneTypes.Slice; AssemblyGenerator: TYPE = SVScene.AssemblyGenerator; SliceList: TYPE = SVSceneTypes.SliceList; BoundBox: TYPE = SVBasicTypes.BoundBox; Camera: TYPE = SVModelTypes.Camera; Color: TYPE = Imager.Color; CoordSysGenerator: TYPE = SVScene.CoordSysGenerator; CoordSystem: TYPE = SVModelTypes.CoordSystem; CSGTree: TYPE = SVRayTypes.CSGTree; EditToolData: TYPE = SVInterfaceTypes.EditToolData; FrameBox: TYPE = SVModelTypes.FrameBox; Matrix4by4: TYPE = SVModelTypes.Matrix4by4; PlanarSurface: TYPE = SVSceneTypes.PlanarSurface; Point2d: TYPE = SV2d.Point2d; Point3d: TYPE = SV3d.Point3d; Rectangle: TYPE = Imager.Rectangle; Sandwich: TYPE = BufferedRefresh.Sandwich; Scene: TYPE = SVSceneTypes.Scene; Selection: TYPE = SVInterfaceTypes.Selection; SelectionClass: TYPE = SVSelect.SelectionClass; SelectionGenerator: TYPE = SVInterfaceTypes.SelectionGenerator; SelectionType: TYPE = SVInterfaceTypes.SelectionType; -- {target, movee, plane}; Shape: TYPE = SVSceneTypes.Shape; SliceDescriptor: TYPE = SVSceneTypes.SliceDescriptor; SliceDescriptorGenerator: TYPE = SVSceneTypes.SliceDescriptorGenerator; SliceParts: TYPE = SVSceneTypes.SliceParts; ToolData: TYPE = SVSceneTypes.ToolData; SVData: TYPE = SVInterfaceTypes.SVData; CreateSandwich: PUBLIC PROC [] RETURNS [sandwich: Sandwich] = { sandwich _ BufferedRefresh.CreateSandwich[LIST[ [$Background, TRUE, RefreshBackground], -- back ... [$Overlay, FALSE, RefreshOverlay], [$SelectionPlane, FALSE, RefreshSelectionPlane], [$SkitterPlane, FALSE, RefreshSkitterPlane]]]; -- ... to front }; ActionAreaPaint: PUBLIC PROC [screen: Imager.Context, whatHasChanged: ATOM, svData: SVData] = { DoActionAreaPaint[screen, whatHasChanged, svData]; }; DoActionAreaPaint: PROC [screen: Imager.Context, whatHasChanged: ATOM, svData: SVData] = { <> <> showColors: BOOL; IF svData.refresh.suppressRefresh THEN RETURN; showColors _ NOT svData.doubleBuffer; SELECT whatHasChanged FROM $None => NULL; $FrameChanged => PaintAllPlanes[screen, svData, showColors, FALSE, FALSE]; $DrawPlane => PaintAllPlanes[screen, svData, showColors, FALSE, FALSE]; $PaintEntireScene => PaintEntireScene[screen, svData, showColors]; $ViewersPaintEntireScene => PaintEntireScene[screen, svData, showColors]; $SelectionChanged => SelectionOrCaretChanged[screen, svData, showColors]; $FinishedDragging => FinishedDragging[screen, svData, showColors]; $SkitterMoved => SelectionOrCaretChanged[screen, svData, showColors]; $AnchorAdded => PaintAllPlanes[screen, svData, showColors, FALSE, FALSE]; $AnchorRemoved => PaintAllPlanes[screen, svData, showColors, FALSE, FALSE]; <> $DuringMotion => PaintDragOverlay[screen, svData, TRUE, showColors]; $DuringSkitterPos => PaintDragOverlay[screen, svData, FALSE, showColors]; $DuringSelect => DuringSelect[screen, svData, showColors]; <<$ObjectChangedInPlace => ObjectChangedInPlace[screen, svData, normal];>> $ObjectChangedBoundBoxProvided => PaintEntireScene[screen, svData, showColors]; $ObjectAdded => PaintEntireScene[screen, svData, showColors]; <> $DrawBlackAndWhite => DrawBlackAndWhite[screen, svData]; $DrawColor => DrawColor[screen, svData]; $DrawCoordSystems => DrawCoordSystems[screen, svData]; $DrawBoundBoxes => DrawBoundBoxes[screen, svData]; $DrawBoundSpheres => DrawBoundSpheres[screen, svData]; $DrawRayCastProgress => DrawRayCastProgress[screen, svData]; $DrawCrossHairs => DrawCrossHairs[screen, svData]; $DrawPt => DrawPt[screen, svData]; $DrawPaint => DrawPaint[screen, svData]; <<$DrawCatScan => DrawCatScan[screen, svData];>> $PaintSpot => PaintSpot[screen, svData]; $PaintHitLine => PaintHitLine[screen, svData]; ENDCASE => { Feedback.Append[svData.feedback, Rope.Cat["SVRefreshImpl doesn't know how to ", Atom.GetPName[whatHasChanged], "."], oneLiner]; Feedback.Blink[svData.feedback]; }; }; DrawRayCastProgress: PROC [screen: Imager.Context, svData: SVData] = { camera: Camera _ svData.camera; width: REAL _ 10; box: Imager.Rectangle; lowLeft, upRight: Point2d; currentY, minX, minY, maxX, maxY: REAL; currentY _ svData.refresh.currentY; minX _ svData.refresh.minX; minY _ svData.refresh.minY; maxX _ svData.refresh.maxX; maxY _ svData.refresh.maxY; lowLeft _ CoordSys.CameraToScreen[[minX, minY], camera.screenCS]; upRight _ CoordSys.CameraToScreen[[maxX, currentY], camera.screenCS]; box _ [lowLeft[1], lowLeft[2], upRight[1] - lowLeft[1], upRight[2] - lowLeft[2]]; Imager.SetColor[screen, Imager.black]; Imager.MaskRectangle[screen, box]; }; PaintEntireScene: PROC [screen: Imager.Context, svData: SVData, showColors: BOOL] = { sandwich: BufferedRefresh.Sandwich _ svData.refresh.sandwich; CodeTimer.StartInt[$PaintEntireScene, $Solidviews]; BufferedRefresh.SetLayerOK[sandwich, $Background, FALSE]; BufferedRefresh.SetLayerOK[sandwich, $SkitterPlane, FALSE]; PaintAllPlanes[screen, svData, showColors, FALSE, FALSE]; CodeTimer.StopInt[$PaintEntireScene, $Solidviews]; }; PaintAllPlanes: PROC [screen: Imager.Context, svData: SVData, showColors: BOOL, caretIsMoving: BOOL, dragInProgress: BOOL] = { sandwich: BufferedRefresh.Sandwich _ svData.refresh.sandwich; clientToViewer, viewerToClient: Imager.Transformation; ignoreBackingMap: BOOL; IF svData.refresh.suppressRefresh THEN RETURN; svData.refresh.caretIsMoving _ caretIsMoving; svData.refresh.dragInProgress _ dragInProgress; clientToViewer _ viewerToClient _ ImagerTransformation.Scale[1.0]; ignoreBackingMap _ showColors; BufferedRefresh.DrawSandwich[sandwich, screen, clientToViewer, viewerToClient, svData, ignoreBackingMap]; }; <<>> <> RefreshBackground: PROC [dc: Imager.Context, boundRect: Rectangle, clientData: REF ANY] = { svData: SVData _ NARROW[clientData]; camera: Camera _ svData.camera; lo, hi: Point2d; lo _ [boundRect.x, boundRect.y]; -- in screen coords hi _ [boundRect.x + boundRect.w, boundRect.y + boundRect.h]; lo _ CoordSys.ScreenToCamera[lo, camera.screenCS]; hi _ CoordSys.ScreenToCamera[hi, camera.screenCS]; DrawObjectsFiltered[dc, svData, SVBoundBox.BoundBoxFromValues[lo[1], lo[2], hi[1], hi[2]], FALSE, -Real.LargestNumber]; }; RefreshOverlay: PROC [dc: Imager.Context, boundRect: Rectangle, clientData: REF ANY] = { <> DrawDragOverlayAux: PROC = { IF svData.refresh.orderedOverlayList=NIL THEN svData.refresh.orderedOverlayList _ OrderOverlayList[svData]; -- update ordered list SELECT camera.style FROM wire, normals => { FOR list: LIST OF SliceDescriptor _ svData.refresh.orderedOverlayList, list.rest UNTIL list = NIL DO SVAssembly.DrawTransform[list.first, dc, scene, camera, svData.drag.transform]; ENDLOOP; }; shaded => { predictedBufferSize: NAT _ CountSurfacesInAssembly[scene.assembly]; polygonBuffer: PriorityQueue.Ref _ PriorityQueue.Predict[predictedBufferSize, DeeperPlanarPolygon]; FOR list: LIST OF SliceDescriptor _ svData.refresh.orderedOverlayList, list.rest UNTIL list = NIL DO IF NOT SVBoundBox.OutsideOf[SVAssembly.GetBoundBox[list.first.slice, NIL, camera], filter] THEN SVAssembly.AddPolygonsToBufferTransform[polygonBuffer, list.first, scene, camera, svData.drag.transform]; ENDLOOP; SVAssembly.DrawBuffer[dc, polygonBuffer, scene, camera]; }; ENDCASE => ERROR; }; svData: SVData _ NARROW[clientData]; scene: Scene _ svData.scene; camera: Camera _ svData.camera; filter: BoundBox _ SVBoundBox.BoundBoxFromRectangle[boundRect, camera]; IF svData.refresh.suppressRefresh THEN RETURN; Imager.DoSaveAll[dc, DrawDragOverlayAux]; }; RefreshSelectionPlane: PROC [dc: Imager.Context, boundRect: Rectangle, clientData: REF ANY] = { svData: SVData _ NARROW[clientData]; camera: Camera _ svData.camera; scene: Scene _ svData.scene; caretIsMoving: BOOL _ svData.refresh.caretIsMoving; dragInProgress: BOOL _ svData.refresh.dragInProgress; IF svData.refresh.suppressRefresh THEN RETURN; <> Imager.SetColor[dc, Imager.black]; IF caretIsMoving OR dragInProgress THEN RETURN; IF svData.showCoordSys THEN DrawCoordSystems[dc, svData]; DrawAnySelectionsDCAux[dc, movee, svData, scene, camera]; DrawAnySelectionsDCAux[dc, target, svData, scene, camera]; DrawAnySelectionsDCAux[dc, plane, svData, scene, camera]; DrawCpsOfSelectedSlices[dc, scene, camera, dragInProgress, caretIsMoving]; }; RefreshSkitterPlane: PROC [dc: Imager.Context, boundRect: Rectangle, clientData: REF ANY] = { svData: SVData _ NARROW[clientData]; camera: Camera _ svData.camera; Imager.SetColor[dc, Imager.black]; DrawSkitter[dc, svData.editToolData, camera]; DrawAnchor[dc, svData, camera]; }; <<>> <> DrawCpsOfSelectedSlices: PROC [dc: Imager.Context, scene: Scene, camera: Camera, dragInProgress, caretIsMoving: BOOL] = { normalSliceD, hotSliceD: SliceDescriptor; normalParts, hotParts: SliceParts; slice: Slice; IF caretIsMoving OR dragInProgress THEN RETURN; FOR sList: LIST OF Slice _ AllSelectedSlices[scene], sList.rest UNTIL sList=NIL DO slice _ sList.first; normalSliceD _ SVSelect.FindSelectedSlice[slice, scene, normal]; hotSliceD _ SVSelect.FindSelectedSlice[slice, scene, hot]; normalParts _ IF normalSliceD # NIL THEN normalSliceD.parts ELSE NIL; hotParts _ IF hotSliceD # NIL THEN hotSliceD.parts ELSE NIL; SVAssembly.DrawSelectionFeedback[slice, normalParts, hotParts, dc, camera, dragInProgress, caretIsMoving, FALSE, caretIsMoving]; ENDLOOP; }; AllSelectedSlices: PROC [scene: Scene] RETURNS [selectedList: LIST OF Slice _ NIL] = { <> ptr: LIST OF Slice; sGen: SliceDescriptorGenerator _ SVSelect.SelectedSlices[scene, hot]; [selectedList, ptr] _ SVUtility.StartSliceList[]; FOR sd: SliceDescriptor _ SVSelect.NextSliceDescriptor[sGen], SVSelect.NextSliceDescriptor[sGen] UNTIL sd = NIL DO [selectedList, ptr] _ SVUtility.AddSlice[sd.slice, selectedList, ptr]; ENDLOOP; sGen _ SVSelect.SelectedSlices[scene, normal]; FOR sd: SliceDescriptor _ SVSelect.NextSliceDescriptor[sGen], SVSelect.NextSliceDescriptor[sGen] UNTIL sd = NIL DO IF NOT SVSelect.IsSelectedInPart[sd.slice, scene, hot] THEN [selectedList, ptr] _ SVUtility.AddSlice[sd.slice, selectedList, ptr]; ENDLOOP; }; DrawAnySelectionsDCAux: PROC [dc: Imager.Context, selType: SelectionType, svData: SVData, scene: Scene, camera: Camera] = { <> g: SelectionGenerator; selectionsExist: BOOL; [g, selectionsExist] _ SVSelections.GetSelectionGenerator[selType]; IF NOT selectionsExist THEN RETURN; FOR sel: Selection _ SVSelections.NextSelection[g], SVSelections.NextSelection[g] UNTIL sel = NIL DO IF sel.svData = svData THEN { DrawSelectionDC[dc, sel, svData]; }; ENDLOOP; }; DrawSelectionDC: PROC [dc: Imager.Context, sel: Selection, svData: SVData] = { DrawSelectionDCAux: SAFE PROC = { Imager.SetColor[dc, Imager.black]; SELECT sel.selectionType FROM target => { csCAMERA: Matrix4by4; csCAMERA _ CoordSys.WRTCamera[sel.coincident.coordSys, camera.coordSys]; SVDraw3d.DrawTargetCoordSys[dc, csCAMERA, camera]; }; movee => SVDraw3d.DrawMovee[dc, sel.coincident.coordSys, camera]; plane => { toolData: ToolData; planeAssem: Slice; planeAssem _ sel.coincident; IF planeAssem.toolMasterObject = NIL OR planeAssem.toolMasterObject.mainBody = NIL THEN ERROR; toolData _ NARROW[planeAssem.toolMasterObject.mainBody]; SVDraw3d.DrawPlaneSelection[dc, sel.coincident.coordSys, toolData.plane, camera]; }; ENDCASE => ERROR; }; camera: Camera; IF svData # sel.svData THEN RETURN; camera _ svData.camera; Imager.DoSave[dc, DrawSelectionDCAux]; }; DrawSkitter: PROC [dc: Imager.Context, editToolData: EditToolData, camera: Camera] = { skitterWORLD, skitterCAMERA: Matrix4by4; IF NOT SVSelections.IsAliveSkitter[editToolData] THEN RETURN; [----, skitterWORLD] _ SVSelections.GetPositionSkitter[editToolData]; skitterCAMERA _ Matrix3d.AInTermsOfB[skitterWORLD, CoordSys.WRTWorld[camera.coordSys]]; SVDraw3d.DrawSkitter[dc, skitterCAMERA, camera]; }; DrawAnchor: PROC [dc: Imager.Context, svData: SVData, camera: Camera] = { anchorWORLD, anchorCAMERA: Matrix4by4; scene: Scene _ svData.scene; IF NOT SVCaret.Exists[scene.anchor] THEN RETURN; anchorWORLD _ SVCaret.GetPosition[scene.anchor]; anchorCAMERA _ Matrix3d.AInTermsOfB[anchorWORLD, CoordSys.WRTWorld[camera.coordSys]]; SVDraw3d.DrawTargetCoordSys[dc, anchorCAMERA, camera]; }; OutsideOf: PROC [test, bound: SVBoundBox.BoundBox] RETURNS [BOOL] = { RETURN[ test.hiX < bound.loX OR test.loX > bound.hiX OR test.hiY < bound.loY OR test.loY > bound.hiY ]; -- these tests may have to be <= or >= }; DeeperPlanarPolygon: PROC [x,y: PriorityQueue.Item, data: REF _ NIL] RETURNS [BOOL] = { xS: PlanarSurface _ NARROW[x]; yS: PlanarSurface _ NARROW[y]; RETURN[xS.depth < yS.depth]; }; DrawObjectsFiltered: PROC [dc: Imager.Context, svData: SVData, filter: BoundBox, excludeOverlay: BOOL _ FALSE, selectedDepth: REAL _ -Real.LargestNumber] = { <> DrawObjectsFilteredAux: PROC = { -- need to clip to filter, then image g: AssemblyGenerator _ SVScene.PrimAssembliesInScene[scene]; thisSlice: Slice _ SVScene.NextAssembly[g]; <> <> <> <<};>> Imager.SetColor[dc, Imager.black]; SVBoundBox.Clip[dc: dc, bBox: filter, screen: camera.screenCS]; SELECT camera.style FROM wire, normals => { FOR slice: Slice _ thisSlice, SVScene.NextAssembly[g] UNTIL slice = NIL DO IF excludeOverlay AND slice.onOverlay THEN LOOP; IF NOT SVBoundBox.OutsideOf[SVAssembly.GetBoundBox[slice, NIL, camera], filter] THEN SVAssembly.DrawParts[slice, NIL, dc, scene, camera, FALSE]; ENDLOOP; }; shaded => { predictedBufferSize: NAT _ CountSurfacesInAssembly[scene.assembly]; polygonBuffer: PriorityQueue.Ref _ PriorityQueue.Predict[predictedBufferSize, DeeperPlanarPolygon]; FOR slice: Slice _ thisSlice, SVScene.NextAssembly[g] UNTIL slice = NIL DO IF excludeOverlay AND slice.onOverlay THEN LOOP; IF NOT SVBoundBox.OutsideOf[SVAssembly.GetBoundBox[slice, NIL, camera], filter] THEN SVAssembly.AddPolygonsToBuffer[polygonBuffer, slice, camera]; ENDLOOP; SVAssembly.DrawBuffer[dc, polygonBuffer, scene, camera]; }; ENDCASE => ERROR; }; scene: Scene _ svData.scene; camera: Camera _ svData.camera; IF filter=NIL OR filter.null THEN RETURN; Imager.DoSaveAll[dc, DrawObjectsFilteredAux]; }; CountSurfacesInAssembly: PROC [assembly: Slice] RETURNS [surfCount: NAT] = { WITH assembly.shape SELECT FROM assems: SliceList => surfCount _ CountSurfacesInAssemblyList[assems]; shape: Shape => surfCount _ shape.mo.class.countSurf[shape.mo]; ENDCASE => ERROR; }; CountSurfacesInAssemblyList: PROC [asl: SliceList] RETURNS [surfCount: NAT] = { surfCount _ 0; FOR list: LIST OF Slice _ asl.list, list.rest UNTIL list = NIL DO surfCount _ surfCount + CountSurfacesInAssembly[list.first]; ENDLOOP; }; DrawCPFeedback: PROC [dc: Imager.Context, svData: SVData, caretIsMoving, dragInProgress: BOOL] = { }; SelectionOrCaretChanged: PROC [screen: Imager.Context, svData: SVData, showColors: BOOL] = { <> PaintAllPlanes[screen, svData, showColors, FALSE, FALSE]; }; <<>> <> DepthOfAssembly: PROC [slice: REF ANY] RETURNS [depth: REAL] = { depth _ -Real.LargestNumber; }; ObjectAdded: PROC [screen: Imager.Context, svData: SVData, showColors: BOOL] = { <> assembly: Slice _ NARROW[svData.refresh.addedObject]; <> bBox: BoundBox _ NIL; selectedDepth: REAL _ DepthOfAssembly[svData.refresh.addedObject]; RepairBackgroundInBoundBox[svData, bBox, FALSE, selectedDepth, showColors]; PaintAllPlanes[screen, svData, showColors, FALSE, FALSE]; }; RepairBackgroundInBoundBox: PROC [svData: SVData, bBox: BoundBox, eraseFirst: BOOL _ FALSE, selectedDepth: REAL, showColors: BOOL] = { backgroundContext: Imager.Context _ BufferedRefresh.GetLayerContext[svData.refresh.sandwich, $Background]; IF NOT showColors THEN { PaintObjectsInBox: PROC = { <> DrawObjectsFiltered[dc: backgroundContext, svData: svData, filter: bBox, selectedDepth: selectedDepth]; }; Imager.DoSaveAll[backgroundContext, PaintObjectsInBox]; BufferedRefresh.SetLayerOK[svData.refresh.sandwich, $Background, TRUE]; }; }; <> PaintDragOverlay: PROC [screen: Imager.Context, svData: SVData, dragInProgress: BOOL, showColors: BOOL] = { <> clientToViewer, viewerToClient: Imager.Transformation; svData.refresh.dragInProgress _ dragInProgress; svData.refresh.caretIsMoving _ TRUE; clientToViewer _ viewerToClient _ ImagerTransformation.Scale[1.0]; BufferedRefresh.DrawSandwich[svData.refresh.sandwich, screen, clientToViewer, viewerToClient, svData, showColors]; }; BackmostSelectedDepth: PROC [scene: Scene] RETURNS [selectedDepth: REAL] = { <> <> <> <> <> <> <> RETURN[-Real.LargestNumber]; }; FinishedDragging: PROC [screen: Imager.Context, svData: SVData, showColors: BOOL] = { scene: Scene _ svData.scene; camera: Camera _ svData.camera; selectedDepth: REAL _ BackmostSelectedDepth[scene]; SVBoundBox.EnlargeByBox[svData.refresh.startBoundBox, SVBoundBox.BoundBoxOfMoving[scene, camera]]; MergeBackgroundAndOverlay[svData, svData.refresh.startBoundBox, TRUE, selectedDepth, showColors]; PaintAllPlanes[screen, svData, showColors, FALSE, FALSE]; }; MergeBackgroundAndOverlay: PROC [svData: SVData, bBox: BoundBox, eraseFirst: BOOL _ FALSE, selectedDepth: REAL, showColors: BOOL] = { <> MergeBackgroundAndOverlayAux: PROC = { IF eraseFirst THEN SVBoundBox.EraseWithinBoundBox[backgroundContext, bBox, camera.screenCS]; DrawObjectsFiltered[dc: backgroundContext, svData: svData, filter: bBox, selectedDepth: selectedDepth]; }; camera: Camera _ svData.camera; backgroundContext: Imager.Context _ BufferedRefresh.GetLayerContext[svData.refresh.sandwich, $Background]; IF svData.refresh.suppressRefresh THEN RETURN; IF NOT showColors THEN { Imager.DoSaveAll[backgroundContext, MergeBackgroundAndOverlayAux]; BufferedRefresh.SetLayerOK[svData.refresh.sandwich, $Background, TRUE]; }; }; <<>> DuringSelect: PROC [screen: Imager.Context, svData: SVData, showColors: BOOL] = { <> IF svData.refresh.suppressRefresh THEN RETURN; IF NOT showColors THEN { clientToViewer, viewerToClient: Imager.Transformation; clientToViewer _ viewerToClient _ ImagerTransformation.Scale[1.0]; BufferedRefresh.DrawSandwich[svData.refresh.sandwich, screen, clientToViewer, viewerToClient, svData, showColors]; } ELSE {}; -- no feedback in SlowPaint mode }; SplitBackgroundAndOverlay: PUBLIC PROC [svData: SVData, restoreBox: BoundBox] = { PaintAllButOverlayed: PROC = { SVBoundBox.EraseWithinBoundBox[backgroundContext, restoreBox, camera.screenCS]; DrawObjectsFiltered[dc: backgroundContext, svData: svData, filter: restoreBox, excludeOverlay: TRUE, selectedDepth: -Real.LargestNumber]; }; backgroundContext: Imager.Context; camera: Camera _ svData.camera; IF svData.refresh.suppressRefresh THEN RETURN; backgroundContext _ BufferedRefresh.GetLayerContext[svData.refresh.sandwich, $Background]; Imager.DoSaveAll[backgroundContext, PaintAllButOverlayed]; }; <<>> <> DrawColor: PROC [dc: Imager.Context, svData: SVData] = { scene: Scene _ svData.scene; resolution: REAL; boundBox: BoundBox; minX, minY, maxX, maxY: REAL; camera: Camera _ svData.camera; tree: CSGTree; screenMat: Matrix4by4; aisRope: Rope.ROPE _ Rope.Concat[SVFiles.FilenameMinusExtension[scene.name], ".ais"]; resolution _ camera.resolution; tree _ DisplayListToTree.AssemblyToTree[scene.assembly, scene, camera]; [minX, minY, maxX, maxY] _ MinAndMaxFromCameraAndTree[camera, tree]; boundBox _ SVBoundBox.BoundBoxFromValues[minX, minY, maxX, maxY]; screenMat _ CoordSys.GetMat[camera.screenCS]; SVImage.DrawAlignedColorImage[dc, aisRope, resolution, [screenMat[1][4], screenMat[2][4]], boundBox, svData.feedback]; }; DrawBlackAndWhite: PROC [dc: Imager.Context, svData: SVData] = { scene: Scene _ svData.scene; camera: Camera _ svData.camera; resolution: REAL; boundBox: BoundBox; minX, minY, maxX, maxY: REAL; tree: CSGTree; screenMat: Matrix4by4; aisRope: Rope.ROPE _ Rope.Concat[SVFiles.FilenameMinusExtension[scene.name], ".ais"]; resolution _ camera.resolution; tree _ DisplayListToTree.AssemblyToTree[scene.assembly, scene, camera]; [minX, minY, maxX, maxY] _ MinAndMaxFromCameraAndTree[camera, tree]; boundBox _ SVBoundBox.BoundBoxFromValues[minX, minY, maxX, maxY]; screenMat _ CoordSys.GetMat[camera.screenCS]; SVImage.DrawAlignedBlackAndWhiteImage[dc, aisRope, resolution, [screenMat[1][4], screenMat[2][4]], boundBox, svData.feedback]; Imager.SetColor[dc, Imager.black]; SVGraphics.DrawFrame [dc, camera]; }; MinAndMaxFromCameraAndTree: PROC [camera: Camera, tree: CSGTree] RETURNS [minX, minY, maxX, maxY: REAL] = { frame: FrameBox _ camera.frame; boundBox: BoundBox; defaultHalfSide: REAL = 100.0; IF frame.fullScreen THEN { [boundBox] _ Preprocess3d.PreprocessForInteraction[tree, camera]; IF boundBox = NIL THEN { minX _ minY _ -defaultHalfSide; maxX _ maxY _ defaultHalfSide; } ELSE { minX _ boundBox.loX; minY _ boundBox.loY; maxX _ boundBox.hiX; maxY _ boundBox.hiY; }; } ELSE { minX _ frame.downLeft[1]; minY _ frame.downLeft[2]; maxX _ frame.upRight[1]; maxY _ frame.upRight[2]; }; }; DrawCoordSystems: PROC [dc: Imager.Context, svData: SVData] = { scene: Scene _ svData.scene; camera: Camera _ svData.camera; g: CoordSysGenerator _ SVScene.GetCoordSysGenerator[scene]; mat: Matrix4by4; FOR cs: CoordSystem _ SVScene.NextCoordSys[g], SVScene.NextCoordSys[g] UNTIL cs = NIL DO mat _ CoordSys.WRTCamera[cs, camera.coordSys]; <> SVDraw3d.DrawCoordSys[dc, mat, camera]; ENDLOOP; }; DrawBoundBoxes: PROC [dc: Imager.Context, svData: SVData] = { scene: Scene _ svData.scene; camera: Camera _ svData.camera; bBox: BoundBox; g: SVScene.AssemblyGenerator _ SVScene.PrimAssembliesInScene[scene]; FOR slice: Slice _ SVScene.NextAssembly[g], SVScene.NextAssembly[g] UNTIL slice = NIL DO bBox _ SVAssembly.GetBoundBox[slice, NIL, camera]; SVBoundBox.DrawBoundBox[dc, bBox, camera.screenCS]; ENDLOOP; }; DrawBoundSpheres: PROC [dc: Imager.Context, svData: SVData] = { scene: Scene _ svData.scene; camera: Camera _ svData.camera; tree: CSGTree; tree _ DisplayListToTree.AssemblyToTree[scene.assembly, scene, camera]; -- does a TellAboutCameraAndWorld [] _ Preprocess3d.PreprocessForCatScan[tree, camera]; -- computes the bounding spheres SVDraw3d.DrawBoundSpheres[dc, tree, camera]; }; <<>> DrawCrossHairs: PROC [dc: Imager.Context, svData: SVData] = { camera: Camera _ svData.camera; SVDraw3d.Draw2dCoordSys[dc, [0,0], camera]; }; DrawPt: PROC [dc: Imager.Context, svData: SVData] = { camera: Camera _ svData.camera; x, y: REAL; [x, y] _ SVUtility.ReadTwoReals[svData.textSection.xyz]; SVDraw3d.DrawX[dc, [x, y], camera]; }; DrawPaint: PROC [dc: Imager.Context, svData: SVData] = { OPEN Matrix3d; camera: Camera _ svData.camera; skitterWORLD, worldCamera: Matrix4by4; path: ImagerPath.Trajectory; editToolData: EditToolData _ svData.editToolData; artworkToolData: ArtworkToolData _ NARROW[editToolData.artworkTool.data]; paintColor: Color _ artworkToolData.paintColor; [----, skitterWORLD] _ SVSelections.GetPositionSkitter[editToolData]; worldCamera _ CoordSys.FindWorldInTermsOf[camera.coordSys]; SVGraphics.MoveToAbsolute[path, Update[Update[[-2, -2, 0], skitterWORLD], worldCamera], camera]; SVGraphics.LineToAbsolute[path, Update[Update[[-2, 2, 0], skitterWORLD], worldCamera], camera]; SVGraphics.LineToAbsolute[path, Update[Update[[2, 2, 0], skitterWORLD], worldCamera], camera]; SVGraphics.LineToAbsolute[path, Update[Update[[2, -2, 0], skitterWORLD], worldCamera], camera]; Imager.SetColor[dc, paintColor]; SVGraphics.DrawStroke[dc, path, 1, TRUE]; }; <> <> <> <> <<};>> <<>> PaintSpot: PUBLIC PROC [dc: Imager.Context, svData: SVData] = { spotPoint: Point2d _ svData.refresh.spotPoint; camera: Camera _ svData.camera; SVDraw3d.DrawX[dc, spotPoint, camera]; }; PaintHitLine: PUBLIC PROC [dc: Imager.Context, svData: SVData] = { spotPoint: Point2d _ svData.refresh.spotPoint; -- in Camera hitPoint: Point3d _ svData.refresh.hitPoint; -- in WORLD scene: Scene _ svData.scene; camera: Camera _ svData.camera; hitPoint _ CoordSys.FromCSToCS[hitPoint, scene.coordSysRoot, camera.coordSys]; SVGraphics.SetCPAbsolute[dc, [spotPoint[1], spotPoint[2], 0.0], camera]; SVGraphics.DrawToAbsolute[dc, hitPoint, camera]; }; <<>> <> InterpressEntireScene: PUBLIC PROC [dc: Imager.Context, svData: SVData] = { scene: Scene _ svData.scene; camera: Camera _ svData.camera; lo, hi: Point2d; lo _ [0,0]; hi _ [8.5*72.0, 11.0*72.0]; lo _ CoordSys.ScreenToCamera[lo, camera.screenCS]; hi _ CoordSys.ScreenToCamera[hi, camera.screenCS]; <> DrawObjectsFiltered[dc, svData, SVBoundBox.BoundBoxFromValues[lo[1], lo[2], hi[1], hi[2]] ]; }; <<>> <> OnOverlay: PROC [entity: REF ANY, svData: SVData] RETURNS [BOOL] = { WITH entity SELECT FROM slice: Slice => RETURN[slice.onOverlay]; sliceD: SliceDescriptor => RETURN[sliceD.slice.onOverlay]; ENDCASE => ERROR; }; MoveToOverlay: PUBLIC PROC [entity: REF ANY, svData: SVData] = { WITH entity SELECT FROM sliceD: SliceDescriptor => { IF OnOverlay[sliceD, svData] THEN ERROR; sliceD.slice.onOverlay _ TRUE; svData.refresh.overlayList _ CONS[sliceD, svData.refresh.overlayList]; }; ENDCASE => ERROR; svData.refresh.orderedOverlayList _ NIL; }; MoveToBackground: PUBLIC PROC [entity: REF ANY, svData: SVData] = { IF NOT OnOverlay[entity, svData] THEN RETURN; svData.refresh.overlayList _ NARROW[GList.DRemove[entity, svData.refresh.overlayList]]; WITH entity SELECT FROM sliceD: SliceDescriptor => sliceD.slice.onOverlay _ FALSE; ENDCASE => ERROR; svData.refresh.orderedOverlayList _ NIL; }; MoveAllSelectedToOverlay: PUBLIC PROC [svData: SVData, selectClass: SelectionClass] = { sGen: SliceDescriptorGenerator _ SVSelect.SelectedSlices[svData.scene, selectClass]; FOR sliceD: SliceDescriptor _ SVSelect.NextSliceDescriptor[sGen], SVSelect.NextSliceDescriptor[sGen] UNTIL sliceD = NIL DO MoveToOverlay[sliceD, svData]; ENDLOOP; }; MoveOverlayToBackground: PUBLIC PROC [svData: SVData] = { sliceD: SliceDescriptor; FOR overlayList: LIST OF SliceDescriptor _ svData.refresh.overlayList, overlayList.rest UNTIL overlayList = NIL DO sliceD _ overlayList.first; sliceD.slice.onOverlay _ FALSE; ENDLOOP; svData.refresh.overlayList _ NIL; svData.refresh.orderedOverlayList _ NIL; }; EmptyOverlay: PUBLIC PROC [svData: SVData] RETURNS [BOOL] = { RETURN[svData.refresh.overlayList = NIL]; }; OrderOverlayList: PROC [svData: SVData] RETURNS [orderedList: LIST OF SliceDescriptor _ NIL] = { <> FindOverlayedD: PROC [slice: REF ANY] RETURNS [sliceD: SliceDescriptor _ NIL] = { FOR ov: LIST OF SliceDescriptor _ svData.refresh.overlayList, ov.rest UNTIL ov=NIL DO sliceD _ ov.first; IF sliceD.slice=slice THEN RETURN[sliceD]; ENDLOOP; RETURN[NIL]; }; sliceD: SliceDescriptor; finger: LIST OF SliceDescriptor; g: SVScene.AssemblyGenerator; scene: Scene _ svData.scene; [orderedList, finger] _ SVUtility.StartSliceDescriptorList[]; g _ SVScene.PrimAssembliesInScene[scene]; FOR slice: Slice _ SVScene.NextAssembly[g], SVScene.NextAssembly[g] UNTIL slice = NIL DO IF OnOverlay[slice, svData] THEN { sliceD _ FindOverlayedD[slice]; IF sliceD = NIL THEN sliceD _ SVAssembly.NewParts[slice, NIL, [0,0,0], topLevel]; [orderedList, finger] _ SVUtility.AddSliceDescriptor[sliceD, orderedList, finger]; }; ENDLOOP; }; InitStats: PROC = { interval: CodeTimer.Interval; interval _ CodeTimer.CreateInterval[$PaintEntireScene]; CodeTimer.AddInt[interval, $Solidviews]; }; InitStats[]; END.