<> <> <> <> <<>> DIRECTORY Atom, BufferedRefresh, CodeTimer, Feedback, FunctionCache, GGBoundBox, GGViewerOps, Imager, ImagerPath, ImagerTransformation, PriorityQueue, Real, Rope, SV2d, SV3d, SVAlign, SVAssembly, SVBasicTypes, SVBoundBox, SVCaret, SVCoordSys, SVDraw3d, SVFiles, SVGraphics, SVImage, SVInterfaceTypes, SVMatrix3d, SVModelTypes, SVPolygon3d, SVPreprocess3d, SVRefresh, SVScene, SVSceneToTree, SVSceneTypes, SVSelect, SVSelections, SVState, SVUtility; SVRefreshImpl: CEDAR PROGRAM IMPORTS Atom, BufferedRefresh, CodeTimer, Feedback, FunctionCache, GGBoundBox, GGViewerOps, Imager, ImagerTransformation, PriorityQueue, Rope, SVAlign, SVAssembly, SVBoundBox, SVCaret, SVCoordSys, SVDraw3d, SVFiles, SVGraphics, SVImage, SVMatrix3d, SVPreprocess3d, SVScene, SVSceneToTree, SVSelect, SVSelections, SVState, SVUtility EXPORTS SVRefresh = BEGIN AlignmentLine: TYPE = SVInterfaceTypes.AlignmentLine; AlignmentObject: TYPE = SVSceneTypes.AlignmentObject; AlignmentPoint: TYPE = SVInterfaceTypes.AlignmentPoint; ArtworkToolData: TYPE = SVInterfaceTypes.ArtworkToolData; 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 = SVSceneTypes.CSGTree; EditToolData: TYPE = SVInterfaceTypes.EditToolData; FeatureData: TYPE = SVInterfaceTypes.FeatureData; 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; Skitter: TYPE = SVSceneTypes.Skitter; Slice: TYPE = SVSceneTypes.Slice; 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], [$Foreground, TRUE, RefreshForeground], [$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 _ SVState.GetShowColors[svData]; SELECT whatHasChanged FROM $None => NULL; $PaintEntireScene, $ViewersPaintEntireScene => PaintEntireScene[screen, svData, showColors]; $ViewersPaintAllPlanes => PaintAllPlanes[screen, svData, showColors, FALSE, FALSE]; $NewAlignmentsDeselected => PaintAllPlanes[screen, svData, showColors, FALSE, FALSE]; $NewAlignmentsSelected => PaintAllPlanes[screen, svData, showColors, FALSE, FALSE]; $SequencesMadeHot => PaintAllPlanes[screen, svData, showColors, FALSE, FALSE]; $SequencesMadeCold => PaintAllPlanes[screen, svData, showColors, FALSE, FALSE]; $SelectionChanged => SelectionOrCaretChanged[screen, svData, showColors]; $FinishedAdding => FinishedAdding[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]; $FrameChanged => PaintAllPlanes[screen, svData, showColors, FALSE, FALSE]; $DrawPlane => 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, showColors]; $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 _ SVCoordSys.CameraToScreen[[minX, minY], camera.screenCS]; upRight _ SVCoordSys.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, $Foreground, FALSE]; BufferedRefresh.SetLayerOK[sandwich, $Background, 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 _ SVCoordSys.ScreenToCamera[lo, camera.screenCS]; hi _ SVCoordSys.ScreenToCamera[hi, camera.screenCS]; DrawObjectsFiltered[dc, svData, GGBoundBox.CreateBoundBox[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, hiddenLine => { predictedBufferSize: NAT _ CountSurfacesInAssembly[scene.assembly]; polygonBuffer: PriorityQueue.Ref _ PriorityQueue.Predict[predictedBufferSize, DeeperPlanarPolygon, camera]; eyeWorld: Point3d_SVGraphics.LocalToWorld[[0,0,camera.focalLength], camera.coordSys]; FOR list: LIST OF SliceDescriptor _ svData.refresh.orderedOverlayList, list.rest UNTIL list = NIL DO SVAssembly.AddPolygonsToBufferTransform[polygonBuffer, list.first, scene, camera, eyeWorld, svData.drag.transform]; ENDLOOP; SVAssembly.DrawBuffer[dc, polygonBuffer, scene, camera, camera.style=hiddenLine]; }; 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; IF svData.camera.quality#quality THEN { DrawAttractorFeedback[dc, svData, dragInProgress, caretIsMoving]; DrawCpsOfSelectedSlices[dc, scene, camera, dragInProgress, caretIsMoving]; }; <> IF caretIsMoving OR dragInProgress THEN RETURN; Imager.SetColor[dc, Imager.black]; 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]; }; RefreshForeground: PROC [dc: Imager.Context, boundRect: Rectangle, clientData: REF ANY] = { svData: SVData _ NARROW[clientData]; IF SVState.GetSuppressRefresh[svData] THEN RETURN; FunctionCache.Flush[svData.refresh.lineCache]; SVAlign.DrawAlignBagRegardless[dc, svData.hitTest.alignBag, svData]; }; 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]; }; NoteNewForeground: PUBLIC PROC [alignObjects: LIST OF FeatureData, svData: SVData] = { <> PaintForeground: PROC = { SVAlign.DrawFeatureList[foregroundContext, alignObjects, svData]; }; foregroundContext: Imager.Context _ BufferedRefresh.GetLayerContext[svData.refresh.sandwich, $Foreground]; Imager.DoSave[foregroundContext, PaintForeground]; BufferedRefresh.SetLayerOK[svData.refresh.sandwich, $Foreground, TRUE]; }; <> DrawAttractorFeedback: PROC [dc: Imager.Context, svData: SVData, dragInProgress, caretIsMoving: BOOL] = { <> skitter: Skitter _ svData.editToolData.skitter; scene: Scene _ svData.scene; camera: Camera _ svData.camera; attractor: AlignmentObject _ SVCaret.GetAttractor[skitter]; IF attractor#NIL THEN { WITH attractor SELECT FROM sliceD: SliceDescriptor => { selectedD: SliceDescriptor _ SVSelect.FindSelectedSlice[sliceD.slice, scene, normal]; selectedParts: SliceParts _ IF selectedD = NIL THEN NIL ELSE selectedD.parts; SVAssembly.DrawAttractorFeedback[sliceD, selectedParts, dragInProgress, dc, svData.camera]; }; alignLine: AlignmentLine => { FOR list: LIST OF Point3d _ alignLine.triggerPoints, list.rest UNTIL list = NIL DO SVDraw3d.DrawGlow[dc, list.first, camera]; ENDLOOP; }; alignPoint: AlignmentPoint => { IF alignPoint.curve1 # NIL THEN DrawGlowPoints[dc, alignPoint.curve1, camera, scene, dragInProgress]; IF alignPoint.curve2 # NIL THEN DrawGlowPoints[dc, alignPoint.curve2, camera, scene, dragInProgress]; }; ENDCASE; }; }; DrawGlowPoints: PROC [dc: Imager.Context, feature: FeatureData, camera: Camera, scene: Scene, dragInProgress: BOOL] = { WITH feature.shape SELECT FROM alignLine: AlignmentLine => { FOR list: LIST OF Point3d _ alignLine.triggerPoints, list.rest UNTIL list = NIL DO SVDraw3d.DrawGlow[dc, list.first, camera]; ENDLOOP; }; sliceD: SliceDescriptor => { selectedD: SliceDescriptor _ SVSelect.FindSelectedSlice[sliceD.slice, scene, normal]; selectedParts: SliceParts _ IF selectedD = NIL THEN NIL ELSE selectedD.parts; SVAssembly.DrawAttractorFeedback[sliceD, selectedParts, dragInProgress, dc, camera]; }; ENDCASE; }; 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 _ SVCoordSys.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; skitter: Skitter _ editToolData.skitter; IF NOT SVCaret.Exists[skitter] THEN RETURN; skitterWORLD _ SVCaret.GetPosition[skitter]; skitterCAMERA _ SVMatrix3d.AInTermsOfB[skitterWORLD, SVCoordSys.WRTWorld[camera.coordSys]]; Imager.SetColor[dc, Imager.black]; 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 _ SVMatrix3d.AInTermsOfB[anchorWORLD, SVCoordSys.WRTWorld[camera.coordSys]]; Imager.SetColor[dc, Imager.black]; SVDraw3d.DrawAnchor[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.frontDepth < yS.frontDepth]; }; epsilon: REAL _ 1.0E-1; <> <<-- We wish to discover if xs.poly is closer to the eyepoint than ys.poly. Both polys are in camera coordinates.>> <> <> <> <> <> <> <> <> <> <<-- If all xS points are on the camera side of yS THEN xS is closer.>> <> <> <> <> <> < 0;>> <> <> <> <> <> <<-- IF all yS points are on the camera side of xS THEN yS is closer.>> <> <> <> <> <> < 0;>> <> <> <> <> <> <> <<};>> <<>> 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, hiddenLine => { predictedBufferSize: NAT _ CountSurfacesInAssembly[scene.assembly]; polygonBuffer: PriorityQueue.Ref _ PriorityQueue.Predict[predictedBufferSize, DeeperPlanarPolygon, camera]; eyeWorld: Point3d_SVGraphics.LocalToWorld[[0,0,camera.focalLength], camera.coordSys]; 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, eyeWorld]; ENDLOOP; SVAssembly.DrawBuffer[dc, polygonBuffer, scene, camera, camera.style=hiddenLine]; }; 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]; }; <<>> <> ObjectChangedInPlace: PROC [screen: Imager.Context, svData: SVData, selectClass: SelectionClass _ normal, showColors: BOOL] = { <> bBox: BoundBox _ SVBoundBox.BoundBoxOfSelected[svData.scene, svData.camera, selectClass]; RepairBackgroundInBoundBox[svData, bBox, TRUE, 0.0, showColors]; 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]; }; FinishedAdding: PROC [screen: Imager.Context, svData: SVData, showColors: BOOL] = { <> selectedDepth: REAL _ BackmostSelectedDepth[svData.scene]; MergeBackgroundAndOverlay[svData, svData.refresh.startBoundBox, FALSE, selectedDepth, showColors]; PaintAllPlanes[screen, svData, showColors, FALSE, FALSE]; }; 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]; GGBoundBox.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 _ SVSceneToTree.AssemblyToTree[scene.assembly, scene, camera]; [minX, minY, maxX, maxY] _ MinAndMaxFromCameraAndTree[camera, tree]; boundBox _ GGBoundBox.CreateBoundBox[minX, minY, maxX, maxY]; screenMat _ SVCoordSys.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 _ SVSceneToTree.AssemblyToTree[scene.assembly, scene, camera]; [minX, minY, maxX, maxY] _ MinAndMaxFromCameraAndTree[camera, tree]; boundBox _ GGBoundBox.CreateBoundBox[minX, minY, maxX, maxY]; screenMat _ SVCoordSys.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] _ SVPreprocess3d.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 _ SVCoordSys.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 _ SVSceneToTree.AssemblyToTree[scene.assembly, scene, camera]; -- does a TellAboutCameraAndWorld [] _ SVPreprocess3d.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] _ GGViewerOps.GetTwoReals[svData.textSection.xyz]; SVDraw3d.DrawX[dc, [x, y], camera]; }; DrawPaint: PROC [dc: Imager.Context, svData: SVData] = { OPEN SVMatrix3d; camera: Camera _ svData.camera; skitterWORLD, worldCamera: Matrix4by4; path: ImagerPath.Trajectory; editToolData: EditToolData _ svData.editToolData; skitter: Skitter _ editToolData.skitter; artworkToolData: ArtworkToolData _ NARROW[editToolData.artworkTool.data]; paintColor: Color _ artworkToolData.paintColor; skitterWORLD _ SVCaret.GetPosition[skitter]; worldCamera _ SVCoordSys.FindWorldInTermsOf[camera.coordSys]; path _ SVGraphics.MoveToAbsolute[Update[Update[[-2, -2, 0], skitterWORLD], worldCamera], camera]; path _ SVGraphics.LineToAbsolute[path, Update[Update[[-2, 2, 0], skitterWORLD], worldCamera], camera]; path _ SVGraphics.LineToAbsolute[path, Update[Update[[2, 2, 0], skitterWORLD], worldCamera], camera]; path _ 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 _ SVCoordSys.FromCSToCS[hitPoint, scene.coordSysRoot, camera.coordSys]; SVGraphics.SetCPAbsolute[dc, [spotPoint[1], spotPoint[2], 0.0], camera]; SVGraphics.DrawToAbsolute[dc, hitPoint, camera]; }; <<>> <> SnapShot: PUBLIC PROC [dc: Imager.Context, svData: SVData] = { <> boundRect: Rectangle _ [x: 0.0, y: 0.0, w: 8.5*72.0, h: 11.0*72.0]; -- room for 8.5 by 11 pictures for now SnapshotBackground[dc, svData]; RefreshOverlay[dc, boundRect, svData]; -- fortunately, RefreshOverlay doesn't use boundRect }; SnapshotBackground: PROC [dc: Imager.Context, svData: SVData] = { <> scene: Scene _ svData.scene; camera: Camera _ svData.camera; sliceGen: AssemblyGenerator; sliceGen _ SVScene.PrimAssembliesInScene[scene]; RefreshBackground[dc, SVState.GetViewport[svData], svData]; DrawAttractorFeedback[dc, svData, svData.refresh.dragInProgress, svData.refresh.caretIsMoving]; FunctionCache.Flush[svData.refresh.lineCache]; -- need to fully refresh foreground SVAlign.DrawAlignBagRegardless[dc, svData.hitTest.alignBag, svData]; DrawSkitter[dc, svData.editToolData, camera]; DrawAnchor[dc, svData, 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 _ SVCoordSys.ScreenToCamera[lo, camera.screenCS]; hi _ SVCoordSys.ScreenToCamera[hi, camera.screenCS]; <> DrawObjectsFiltered[dc, svData, GGBoundBox.CreateBoundBox[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 [sliceD: SliceDescriptor, svData: SVData] = { IF NOT OnOverlay[sliceD, svData] THEN RETURN; svData.refresh.overlayList _ SVUtility.DeleteSliceDescriptorFromList[sliceD, svData.refresh.overlayList]; sliceD.slice.onOverlay _ FALSE; 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.