DIRECTORY AtomButtonsTypes, CoordSys, SVGraphics, DisplayListToTree, Feedback, Imager, ImagerColor, IO, Matrix3d, Rope, SV2d, SV3d, SVArtwork, SVAssembly, SVMasterObject, SVModelTypes, SVPolygon3d, SVScene, SVScenePrivate, SVSceneTypes, SVToolObject, SVUtility, ViewerClasses; SVSceneImplA: CEDAR PROGRAM IMPORTS CoordSys, SVGraphics, DisplayListToTree, Feedback, SVMasterObject, SVScene, SVScenePrivate, Imager, ImagerColor, IO, Matrix3d, Rope, SVArtwork, SVAssembly, SVPolygon3d, SVToolObject, SVUtility EXPORTS SVScene, SVScenePrivate = BEGIN versionRope: PUBLIC Rope.ROPE _ "Solidviews Version 7.02 OF May 5, 1987 11:11:06 pm PDT"; Artwork: TYPE = SVModelTypes.Artwork; Slice: TYPE = REF SliceObj; SliceList: TYPE = REF SliceListObj; SliceListObj: TYPE = SVSceneTypes.SliceListObj; SliceObj: TYPE = SVSceneTypes.SliceObj; Camera: TYPE = SVGraphics.Camera; Classification: TYPE = SVSceneTypes.Classification; Color: TYPE = Imager.Color; CoordSysList: TYPE = SVModelTypes.CoordSysList; CoordSystem: TYPE = SVModelTypes.CoordSystem; CSGTree: TYPE = SVSceneTypes.CSGTree; Database: TYPE = REF DatabaseObj; DatabaseObj: TYPE = SVSceneTypes.DatabaseObj; DrawStyle: TYPE = SVModelTypes.DrawStyle; FeedbackData: TYPE = AtomButtonsTypes.FeedbackData; FileCamera: TYPE = REF FileCameraObj; FileCameraList: TYPE = SVSceneTypes.FileCameraList; FileCameraObj: TYPE = SVSceneTypes.FileCameraObj; FrameBlock: TYPE = REF FrameBlockObj; FrameBlockObj: TYPE = SVSceneTypes.FrameBlockObj; FrameBox: TYPE = REF FrameBoxObj; FrameBoxObj: TYPE = SVModelTypes.FrameBoxObj; LightSource: TYPE = REF LightSourceObj; LightSourceList: TYPE = SVModelTypes.LightSourceList; LightSourceObj: TYPE = SVModelTypes.LightSourceObj; Matrix4by4: TYPE = SV3d.Matrix4by4; Plane: TYPE = SV3d.Plane; Point2d: TYPE = SV2d.Point2d; Point3d: TYPE = SV3d.Point3d; PointSetOp: TYPE = SVSceneTypes.PointSetOp;-- {union, intersection, difference} Poly3d: TYPE = SV3d.Poly3d; Primitive: TYPE = SVSceneTypes.Primitive; Projection: TYPE = SVModelTypes.Projection; Ray: TYPE = SVSceneTypes.Ray; Scene: TYPE = REF SceneObj; SceneObj: TYPE = SVSceneTypes.SceneObj; Shape: TYPE = REF ShapeObj; ShapeObj: TYPE = SVSceneTypes.ShapeObj; -- allocated in CreateAndAddPrimitiveAssembly, etc. Skitter: TYPE = REF SkitterObj; SkitterObj: TYPE = SVSceneTypes.SkitterObj; ToolData: TYPE = REF ToolDataObj; ToolDataObj: TYPE = SVSceneTypes.ToolDataObj; Vector3d: TYPE = SV3d.Vector3d; Viewer: TYPE = ViewerClasses.Viewer; MasterObjectClass: TYPE = REF MasterObjectClassObj; MasterObjectClassObj: TYPE = SVSceneTypes.MasterObjectClassObj; MasterObjectClassList: TYPE = SVSceneTypes.MasterObjectClassList; UpdateProc: TYPE = SVSceneTypes.UpdateProc; FileinProc: TYPE = SVSceneTypes.FileinProc; FileoutProc: TYPE = SVSceneTypes.FileoutProc; FileoutPolyProc: TYPE = SVSceneTypes.FileoutPolyProc; MasterObject: TYPE = REF MasterObjectRec; MasterObjectRec: TYPE = SVSceneTypes.MasterObjectRec; MasterObjectList: TYPE = SVSceneTypes.MasterObjectList; RayCastProc: TYPE = SVSceneTypes.RayCastProc; RayCastNoBBoxesProc: TYPE = SVSceneTypes.RayCastNoBBoxesProc; RayCastBoundingSpheresProc: TYPE = SVSceneTypes.RayCastBoundingSpheresProc; GetHedronProc: TYPE = SVSceneTypes.GetHedronProc; PreprocessProc: TYPE = SVSceneTypes.PreprocessProc; LineDrawProc: TYPE = SVSceneTypes.LineDrawProc; NormalsDrawProc: TYPE = SVSceneTypes.NormalsDrawProc; CountSurfProc: TYPE = SVSceneTypes.CountSurfProc; GetSurfProc: TYPE = SVSceneTypes.GetSurfProc; PlanarSurface: TYPE = REF PlanarSurfaceObj; PlanarSurfaceObj: TYPE = SVSceneTypes.PlanarSurfaceObj; PlanarSurfaceList: TYPE = SVSceneTypes.PlanarSurfaceList; DrawPlanarSurfaceProc: TYPE = SVSceneTypes.DrawPlanarSurfaceProc; DrawSubBoxesProc: TYPE = SVSceneTypes.DrawSubBoxesProc; DrawSubSpheresProc: TYPE = SVSceneTypes.DrawSubSpheresProc; globalDatabase: Database; CreateScene: PUBLIC PROC [name: Rope.ROPE] RETURNS [scene: Scene] = { worldCS: CoordSystem _ CoordSys.CreateRoot["WORLD"]; sceneAssemblyCS: CoordSystem; sceneAssembly: Slice; ambientLight: LightSource _ CreateAmbientLightSource["Ambient", ImagerColor.ColorFromRGB[[0.2,0.2,0.2]]]; defaultWhiteLight: LightSource _ CreateLightSource["WhiteLight",[800,800,1000], Imager.white]; cameras: FileCameraList _ SVScene.InitialCameraList[]; anchor: Skitter _ NEW[SkitterObj]; anchor.alive _ FALSE; sceneAssemblyCS _ CoordSys.CreateCoordSysInTree["sceneAssembly", Matrix3d.Identity[], worldCS, worldCS]; sceneAssembly _ CreateSceneAssembly["sceneAssembly", union, sceneAssemblyCS, FALSE, NIL]; scene _ NEW[SceneObj _ [ name: name, coordSysRoot: worldCS, lightSources: CONS[ambientLight, CONS[defaultWhiteLight, NIL]], masterObjects: SVScenePrivate.CopyMasterObjectList[SVMasterObject.GetMasterObjectList[]], -- Copies the list structure but not the objects. assembly: sceneAssembly, tree: DisplayListToTree.CreateEmptyTree[], cameras: cameras, anchor: anchor, cameraOrder: LIST["Front"], backgroundColor: Imager.white, shadows: FALSE, dirty: FALSE ]]; globalDatabase _ AppendToDatabase[scene, globalDatabase]; }; CreateEmptyScene: PUBLIC PROC [name: Rope.ROPE] RETURNS [scene: Scene] = { anchor: Skitter _ NEW[SkitterObj]; anchor.alive _ FALSE; scene _ NEW[SceneObj _ [name: name, coordSysRoot: NIL, lightSources: NIL, masterObjects: NIL, assembly: NIL, tree: DisplayListToTree.CreateEmptyTree[], cameras: NIL, anchor: anchor, cameraOrder: NIL, backgroundColor: Imager.white, shadows: FALSE, dirty: FALSE]]; globalDatabase _ AppendToDatabase[scene, globalDatabase]; }; CreateMasterObject: PUBLIC PROC [ name: Rope.ROPE, class: MasterObjectClass, mainBody: REF ANY, lineBody: REF ANY, shadeBody: REF ANY, rayCastBody: REF ANY] RETURNS [mo: MasterObject] = { mo _ NEW[MasterObjectRec _ [name, class, mainBody, lineBody, shadeBody, rayCastBody]]; }; CopyMasterObject: PUBLIC PROC [mo: MasterObject] RETURNS [copy: MasterObject] = { copy _ NEW[MasterObjectRec]; copy.name _ mo.name; copy.class _ mo.class; copy.mainBody _ mo.mainBody; copy.lineBody _ mo.lineBody; copy.shadeBody _ mo.shadeBody; copy.rayCastBody _ mo.rayCastBody; }; CreateSceneAssembly: PUBLIC PROC [name: Rope.ROPE, pointSetOp: PointSetOp, coordSys: CoordSystem, isTool: BOOL _ FALSE, toolData: ToolData _ NIL] RETURNS [assembly: Slice] = { artwork: Artwork _ SVArtwork.CreateColorArtwork[Imager.white, plastic]; -- white toolMasterObject: MasterObject; toolName, base: Rope.ROPE; num: NAT; IF toolData = NIL THEN toolMasterObject _ NIL ELSE { [base, num] _ CoordSys.BaseAndNumber[name]; IF num > 0 THEN toolName _ Rope.Cat[base, "$$tool.", IO.PutFR["%g", [integer[num]]]] ELSE toolName _ Rope.Concat[base, "$$tool"]; toolMasterObject _ SVToolObject.ToolMakeMasterObject[toolName, toolData]; }; assembly _ NEW[SliceObj _ [name: name, coordSys: NIL, artwork: artwork, showAs: normal, isTool: isTool, toolMasterObject: toolMasterObject, shape: NEW[SliceListObj _ [NIL, pointSetOp]] ]]; assembly.coordSys _ coordSys; }; CreateToolData: PUBLIC PROC [loX, hiX, loY, hiY, loZ, hiZ: REAL, plane: NAT, infinite: BOOL _ FALSE, clientData: REF ANY _ NIL] RETURNS [toolData: ToolData] = { block: FrameBlock _ NEW[FrameBlockObj _ [loX, hiX, loY, hiY, loZ, hiZ]]; toolData _ NEW[ToolDataObj _ [block, infinite, plane, clientData]]; }; CreateAmbientLightSource: PUBLIC PROC [name: Rope.ROPE, color: Color] RETURNS [ls: LightSource] = { ls _ NEW[LightSourceObj _ [name, [0,0,0], color, ambient]]; }; CreateLightSource: PUBLIC PROC [name: Rope.ROPE, position: Point3d, color: Color] RETURNS [ls: LightSource] = { ls _ NEW[LightSourceObj _ [name, position, color, point]]; }; CreateFileCamera: PUBLIC PROC [name: Rope.ROPE, origin: Point3d, focusPoint: Point3d, slant: REAL, resolution: REAL, focalLength: REAL, projection: Projection, frame: FrameBox, clippingPlanes: LIST OF Plane, visibleAssemblies: LIST OF Rope.ROPE] RETURNS [fileCamera: FileCamera] = { fileCamera _ NEW[FileCameraObj _ [name, origin, focusPoint, slant, resolution, focalLength, projection, frame, clippingPlanes, visibleAssemblies]]; }; CreateCamera: PUBLIC PROC [worldCS: CoordSystem, screenCS: CoordSystem, style: DrawStyle] RETURNS [camera: Camera] = { cameraName: Rope.ROPE _ CoordSys.UniqueNameFrom["Camera", worldCS]; coordSys: CoordSystem _ CoordSys.CreateCoordSysInTree[name: cameraName, mat: Matrix3d.Identity[], parent: worldCS, root: worldCS]; -- to start with resolution: REAL _ 72.0; focalLength: REAL _ 1800.0; projection: Projection _ perspective; frame: FrameBox _ NIL; clippingPlanes: LIST OF Plane _ NIL; visibleAssemblies: LIST OF Rope.ROPE _ NIL; colorFilm: BOOL _ TRUE; useBoundBoxes: BOOL _ TRUE; useBoundSpheresForShadows: BOOL _ TRUE; camera _ SVGraphics.CreateCamera["NoPlace", coordSys, screenCS, resolution, focalLength, projection, frame, clippingPlanes, visibleAssemblies, style, colorFilm, useBoundBoxes, useBoundSpheresForShadows]; }; StuffCameraFromFileCamera: PUBLIC PROC [camera: Camera, fileCamera: FileCamera, style: DrawStyle, scene: Scene] = { camera.viewName _ fileCamera.name; CoordSys.SetName[camera.coordSys, fileCamera.name]; camera.resolution _ fileCamera.resolution; camera.focalLength _ fileCamera.focalLength; camera.projection _ fileCamera.projection; camera.frame _ fileCamera.frame; camera.clippingPlanes _ fileCamera.clippingPlanes; camera.visibleAssemblies _ fileCamera.visibleAssemblies; camera.style _ style; SVGraphics.PlaceCamera[camera, fileCamera.focusPoint, fileCamera.origin, fileCamera.slant]; UpdateBoundBoxes[scene, camera]; }; UpdateBoundBoxes: PROC [scene: Scene, camera: Camera] = { g: SVScene.AssemblyGenerator _ SVScene.PrimAssembliesInScene[scene]; FOR slice: Slice _ SVScene.NextAssembly[g], SVScene.NextAssembly[g] UNTIL slice = NIL DO SVAssembly.UpdateBoundBoxForCamera[slice, camera]; ENDLOOP; }; InitialCameraList: PUBLIC PROC [] RETURNS [cameras: FileCameraList] = { top, bottom, left, right, front, upLeft, upRight: FileCamera; defaultFocalLength: REAL = 1800; defaultResolution: REAL _ 72.0; frame: FrameBox _ NEW[FrameBoxObj _ [[0,0], [0,0], TRUE]]; hither: Plane _ SVPolygon3d.PlaneFromPointAndNormal[[0,0,0], [0,0,1]]; sAList: LIST OF Rope.ROPE _ LIST["sceneAssembly"]; top _ CreateFileCamera[name: "Top", origin: [0,1800,0], focusPoint: [0,0,0], slant: 0, resolution: defaultResolution, focalLength: defaultFocalLength, projection: perspective, frame: frame, clippingPlanes: LIST[hither], visibleAssemblies: sAList]; bottom _ CreateFileCamera[name: "Bottom", origin: [0,-1800,0], focusPoint: [0,0,0], slant: 0, resolution: defaultResolution, focalLength: defaultFocalLength, projection: perspective, frame: frame, clippingPlanes: LIST[hither], visibleAssemblies: sAList]; left _ CreateFileCamera[name: "Left", origin: [-1800,0,0], focusPoint: [0,0,0], slant: 0, resolution: defaultResolution, focalLength: defaultFocalLength, projection: perspective, frame: frame, clippingPlanes: LIST[hither], visibleAssemblies: sAList]; right _ CreateFileCamera[name: "Right", origin: [1800,0,0], focusPoint: [0,0,0], slant: 0, resolution: defaultResolution, focalLength: defaultFocalLength, projection: perspective, frame: frame, clippingPlanes: LIST[hither], visibleAssemblies: sAList]; front _ CreateFileCamera[name: "Front", origin: [0,0,1800], focusPoint: [0,0,0], slant: 0, resolution: defaultResolution, focalLength: defaultFocalLength, projection: perspective, frame: frame, clippingPlanes: LIST[hither], visibleAssemblies: sAList]; upLeft _ CreateFileCamera[name: "UpLeft", origin: [-600,1200,1800], focusPoint: [0,0,0], slant: 0, resolution: defaultResolution, focalLength: defaultFocalLength, projection: perspective, frame: frame, clippingPlanes: LIST[hither], visibleAssemblies: sAList]; upRight _ CreateFileCamera[name: "UpRight", origin: [600,1200,1800], focusPoint: [0,0,0], slant: 0, resolution: defaultResolution, focalLength: defaultFocalLength, projection: perspective, frame: frame, clippingPlanes: LIST[hither], visibleAssemblies: sAList]; cameras _ LIST[top, bottom, left, right, front, upLeft, upRight]; }; NameAlreadyPresent: PUBLIC SAFE SIGNAL = CODE; AddMasterObjectToScene: PUBLIC PROC [mo: MasterObject, scene: Scene] = { oldMO: MasterObject; success, found: BOOL _ FALSE; [oldMO, success] _ FindObjectFromName[mo.name, scene]; IF success THEN { used: BOOL _ SVScene.MasterObjectIsUsed[oldMO, scene]; IF NOT used THEN { found _ SVScene.DeleteMasterObjectNamed[oldMO.name, scene]; IF NOT found THEN ERROR; } ELSE SIGNAL NameAlreadyPresent; }; scene.masterObjects _ SVUtility.AppendToMasterObjects[mo, scene.masterObjects]; }; AddLightSourceToScene: PUBLIC PROC [ls: LightSource, scene: Scene] = { IF LightSourceNameIsPresent[ls.name, scene] THEN SIGNAL NameAlreadyPresent; scene.lightSources _ AppendToLightSourceList[ls, scene.lightSources]; }; AddCameraToScene: PUBLIC PROC [fileCamera: FileCamera, scene: Scene] = { IF FileCameraNameIsPresent[fileCamera.name, scene] THEN SIGNAL NameAlreadyPresent; scene.cameras _ AppendToFileCameraList[fileCamera, scene.cameras]; }; AddCameraOrderNameToScene: PUBLIC PROC [name: Rope.ROPE, scene: Scene] = { IF CameraOrderNameIsPresent[name, scene] THEN SIGNAL NameAlreadyPresent; scene.cameraOrder _ AppendToCameraOrderList[name, scene.cameraOrder]; }; AddOrResizeToolToAssembly: PUBLIC PROC [assembly: Slice, scene: Scene] = { toolMasterObject: MasterObject; toolData: SVToolObject.ToolData; toolName: Rope.ROPE; IF assembly.toolMasterObject = NIL THEN { toolData _ SVScene.CreateToolData[-100, 100, -100, 100, -100, 100, 3, FALSE]; toolName _ CoordSys.NameWithSuffix[assembly.name, "$$tool", scene.coordSysRoot]; toolMasterObject _ SVToolObject.ToolMakeMasterObject[toolName, toolData]; assembly.toolMasterObject _ toolMasterObject; }; toolData _ NARROW[assembly.toolMasterObject.mainBody]; SVToolObject.SizeToFit[toolData, assembly]; }; AppendToDatabase: PROC [scene: Scene, database: Database] RETURNS [Database] = { z: LIST OF Scene _ database.scenes; IF z = NIL THEN {database.scenes _ CONS[scene,NIL]; RETURN[database]}; UNTIL z.rest = NIL DO z _ z.rest; ENDLOOP; z.rest _ CONS[scene,NIL]; RETURN[database]; }; AppendToLightSourceList: PROC [ls: LightSource, list: LightSourceList] RETURNS [LightSourceList] = { z: LightSourceList _ list; IF z = NIL THEN RETURN[CONS[ls,NIL]]; UNTIL z.rest = NIL DO z _ z.rest; ENDLOOP; z.rest _ CONS[ls,NIL]; RETURN[list]; }; AppendToFileCameraList: PROC [fileCamera: FileCamera, list: FileCameraList] RETURNS [FileCameraList] = { z: FileCameraList _ list; IF z = NIL THEN RETURN[CONS[fileCamera,NIL]]; UNTIL z.rest = NIL DO z _ z.rest; ENDLOOP; z.rest _ CONS[fileCamera,NIL]; RETURN[list]; }; AppendToCameraOrderList: PROC [name: Rope.ROPE, list: LIST OF Rope.ROPE] RETURNS [LIST OF Rope.ROPE] = { z: LIST OF Rope.ROPE _ list; IF z = NIL THEN RETURN[CONS[name,NIL]]; UNTIL z.rest = NIL DO z _ z.rest; ENDLOOP; z.rest _ CONS[name,NIL]; RETURN[list]; }; RenameAssembly: PUBLIC PROC [assem: Slice, newName: Rope.ROPE, scene: Scene] = { assem.name _ newName; CoordSys.SetName[assem.coordSys, newName]; }; MoveSubassembly: PUBLIC PROC [assem: Slice, to: Slice, scene: Scene] = { assemWithSameName, parent: Slice; parentList: SliceList; found: BOOL; toCS: CoordSystem _ to.coordSys; [assemWithSameName, parent] _ FindAssemblyFromName[assem.name, scene]; IF assemWithSameName # assem THEN ERROR; IF NOT SVAssembly.IsComposite[to] THEN SIGNAL AttemptToAddSubassemblyToPrimitive; parentList _ NARROW[parent.shape]; [parent.shape, found] _ SVScenePrivate.TemporaryRemoveFromAssemblyList[assem, parentList, scene]; IF NOT found THEN ERROR;-- it was found just a few lines ago. What happened? [] _ CoordSys.PutAInTermsOfB[assem.coordSys, to.coordSys]; to.shape _ SVUtility.AppendToAssemblyList[assem, NARROW[to.shape]] }; -- end of MoveSubassembly AttemptToAddSubassemblyToPrimitive: PUBLIC SIGNAL = CODE; MoveToFrontOfAssembly: PUBLIC PROC [subassembly: Slice, assembly: Slice, scene: Scene] = { aList: SliceList _ NARROW[assembly.shape]; success: BOOL _ FALSE; FOR list: LIST OF Slice _ aList.list, list.rest UNTIL list = NIL DO IF list.first = subassembly THEN success_TRUE; ENDLOOP; IF NOT success THEN ERROR SubassemblyNotFound; [aList, success] _ SVScenePrivate.TemporaryRemoveFromAssemblyList[subassembly, aList, scene]; IF NOT success THEN ERROR SubassemblyNotFound; aList.list _ CONS[subassembly, aList.list]; }; SubassemblyNotFound: PUBLIC ERROR = CODE; MergeAssemblyIntoScene: PUBLIC PROC [originalAssembly: Slice, fromScene: Scene, parentAssembly: Slice, toScene: Scene, feedback: FeedbackData] RETURNS [copyAssembly: Slice] = { copyAssembly _ SVScene.CopyAssemblyAndSonsUniqueNames [assembly: originalAssembly, oldScene: fromScene, newScene: toScene, parent: parentAssembly, feedback: feedback]; }; MergeSceneIntoScene: PUBLIC PROC [fromScene: Scene, toScene: Scene, feedback: FeedbackData] RETURNS [success: BOOL] = { fromList: SliceList _ NARROW[fromScene.assembly.shape]; toSceneAssembly: Slice _ toScene.assembly; FOR list: LIST OF Slice _ fromList.list, list.rest UNTIL list = NIL DO [] _ MergeAssemblyIntoScene[list.first, fromScene, toSceneAssembly, toScene, feedback]; ENDLOOP; }; SetArtworkAssembly: PUBLIC PROC [assembly: Slice, artwork: Artwork, scene: Scene] = { FOR list: LIST OF Slice _ ListOfPrimAssemblies[assembly, scene], list.rest UNTIL list = NIL DO list.first.artwork _ artwork; ENDLOOP; }; FindSceneFromName: PUBLIC PROC [name: Rope.ROPE] RETURNS [scene: Scene] = { l: LIST OF Scene _ globalDatabase.scenes; IF l = NIL THEN ERROR DatabaseEmpty; UNTIL l = NIL DO IF Rope.Equal[l.first.name, name, FALSE] THEN BEGIN scene _ l.first; RETURN END; l _ l.rest; ENDLOOP; SIGNAL SceneNotFound; }; DatabaseEmpty: PUBLIC SIGNAL = CODE; SceneNotFound: PUBLIC SIGNAL = CODE; FindAssemblyFromName: PUBLIC PROC [name: Rope.ROPE, scene: Scene] RETURNS [assembly: Slice, superAssembly: Slice, success: BOOL] = { t: Slice _ scene.assembly; [assembly, superAssembly, success] _ FindAssemblyInTree[name, t, NIL]; IF NOT success THEN { Feedback.PutFRaw[$Solidviews, oneLiner, "Slice %g not found", [rope[name]]]; Feedback.BlinkRaw[$Solidviews]; }; }; AssemblyNotFound: PUBLIC SIGNAL = CODE; AssemblyNameIsPresent: PUBLIC PROC [name: Rope.ROPE, scene: Scene] RETURNS [BOOL] = { dummy1, dummy2: Slice; isPresent: BOOL; [dummy1, dummy2, isPresent] _ FindAssemblyInTree[name, scene.assembly, NIL]; RETURN[isPresent]; }; FindAssemblyInTree: PRIVATE PROC [name: Rope.ROPE, t: Slice, super: Slice] RETURNS [assembly: Slice, superAssembly: Slice, success: BOOL] = { IF t = NIL THEN RETURN[NIL,NIL,FALSE]; IF Rope.Equal[t.name, name] THEN RETURN[t, super, TRUE]; WITH t.shape SELECT FROM as: SliceList => { FOR l: LIST OF Slice _ as.list, l.rest UNTIL l = NIL DO [assembly, superAssembly, success] _ FindAssemblyInTree[name, l.first, t]; IF success THEN RETURN; ENDLOOP; RETURN [NIL, NIL, FALSE]; }; ENDCASE => -- t is a primitive assembly with the wrong name RETURN[NIL,NIL,FALSE]; }; AnyNamesAlreadyPresent: PUBLIC PROC [assembly: Slice, scene: Scene] RETURNS [BOOL] = { IF AssemblyNameIsPresent[assembly.name, scene] THEN RETURN [TRUE]; WITH assembly.shape SELECT FROM shape: Shape => RETURN[FALSE]; aList: SliceList => RETURN[AnyNamesAlreadyPresentInList[aList, scene]]; ENDCASE => RETURN[FALSE]; }; AnyNamesAlreadyPresentInList: PRIVATE PROC [assemblyList: SliceList, scene: Scene] RETURNS [BOOL] = { FOR list: LIST OF Slice _ assemblyList.list, list.rest UNTIL list = NIL DO IF AnyNamesAlreadyPresent[list.first, scene] THEN RETURN [TRUE]; ENDLOOP; RETURN [FALSE]; }; ObjectNameIsPresent: PUBLIC PROC [name: Rope.ROPE, scene: Scene] RETURNS [BOOL] = { FOR ol: MasterObjectList _ scene.masterObjects, ol.rest UNTIL ol = NIL DO IF Rope.Equal[ol.first.name, name, TRUE] THEN RETURN [TRUE]; ENDLOOP; RETURN[FALSE]; }; FindObjectFromName: PUBLIC PROC [name: Rope.ROPE, scene: Scene] RETURNS [object: MasterObject, success: BOOL] = { FOR ol: MasterObjectList _ scene.masterObjects, ol.rest UNTIL ol = NIL DO IF Rope.Equal[ol.first.name, name, TRUE] THEN RETURN [ol.first, TRUE]; ENDLOOP; RETURN[NIL, FALSE]; }; CoordSysNameIsPresent: PUBLIC PROC [name: Rope.ROPE, scene: Scene] RETURNS [BOOL] = { RETURN[CoordSys.CoordSysNameIsPresent[name, scene.coordSysRoot]]; }; FindLightFromName: PUBLIC PROC [name: Rope.ROPE, scene: Scene] RETURNS [light: LightSource, success: BOOL] = { FOR list: LightSourceList _ scene.lightSources, list.rest UNTIL list = NIL DO IF Rope.Equal[list.first.name, name, TRUE] THEN RETURN [list.first, TRUE]; ENDLOOP; RETURN [NIL, FALSE]; }; LightSourceNameIsPresent: PUBLIC PROC [name: Rope.ROPE, scene: Scene] RETURNS [BOOL] = { FOR ll: LightSourceList _ scene.lightSources, ll.rest UNTIL ll = NIL DO IF Rope.Equal[ll.first.name, name, TRUE] THEN RETURN [TRUE]; ENDLOOP; RETURN[FALSE]; }; FindFileCameraFromName: PUBLIC PROC [name: Rope.ROPE, scene: Scene] RETURNS [fileCamera: FileCamera, success: BOOL] = { FOR list: FileCameraList _ scene.cameras, list.rest UNTIL list = NIL DO IF Rope.Equal[list.first.name, name, TRUE] THEN RETURN [list.first, TRUE]; ENDLOOP; RETURN [NIL, FALSE]; }; FileCameraNameIsPresent: PUBLIC PROC [name: Rope.ROPE, scene: Scene] RETURNS [BOOL] = { FOR list: FileCameraList _ scene.cameras, list.rest UNTIL list = NIL DO IF Rope.Equal[list.first.name, name, TRUE] THEN RETURN [TRUE]; ENDLOOP; RETURN[FALSE]; }; CameraOrderNameIsPresent: PUBLIC PROC [name: Rope.ROPE, scene: Scene] RETURNS [BOOL] = { FOR list: LIST OF Rope.ROPE _ scene.cameraOrder, list.rest UNTIL list = NIL DO IF Rope.Equal[list.first, name, TRUE] THEN RETURN [TRUE]; ENDLOOP; RETURN[FALSE]; }; UniqueObjectNameFrom: PUBLIC PROC [name: Rope.ROPE, scene: Scene] RETURNS [unique: Rope.ROPE] = { maxNum: NAT _ 0; targetBase, base: Rope.ROPE; targetNum, num: NAT; [targetBase, targetNum] _ CoordSys.BaseAndNumber[name]; FOR ol: MasterObjectList _ scene.masterObjects, ol.rest UNTIL ol = NIL DO [base, num] _ CoordSys.BaseAndNumber[ol.first.name]; IF Rope.Equal[base, targetBase, TRUE] THEN maxNum _ MAX[num, maxNum]; ENDLOOP; unique _ IO.PutFR["%g.%g",[rope[targetBase]], [integer[maxNum+1]]]; }; FindMasterObjectAndNeighborsFromName: PUBLIC PROC [moName: Rope.ROPE, moList: MasterObjectList] RETURNS [beforeMo, mo, afterMo: MasterObjectList, found: BOOL] = { lastL: MasterObjectList _ NIL; l: MasterObjectList _ moList; found _ TRUE; IF l = NIL THEN RETURN[NIL, NIL, NIL, FALSE]; UNTIL l = NIL DO IF Rope.Equal[l.first.name, moName, TRUE] THEN { beforeMo _ lastL; mo _ l; afterMo _ l.rest; RETURN}; lastL _ l; l _ l.rest; ENDLOOP; RETURN[NIL, NIL, NIL, FALSE]; }; FindLightSourceAndNeighborsFromName: PUBLIC PROC [lsName: Rope.ROPE, lsList: LightSourceList] RETURNS [beforeLS, ls, afterLS: LightSourceList] = { lastL: LightSourceList _ NIL; l: LightSourceList _ lsList; IF l = NIL THEN ERROR LightSourceNotFound; UNTIL l = NIL DO IF Rope.Equal[l.first.name, lsName] THEN { beforeLS _ lastL; ls _ l; afterLS _ l.rest; RETURN}; lastL _ l; l _ l.rest; ENDLOOP; SIGNAL LightSourceNotFound; }; LightSourceNotFound: PUBLIC SIGNAL = CODE; GetSceneGenerator: PUBLIC PROC RETURNS [g: SceneGenerator] = { g _ NEW[SceneGeneratorObj _ [currentPtr: globalDatabase.scenes]]; }; SceneGenerator: TYPE = REF SceneGeneratorObj; SceneGeneratorObj: TYPE = SVScene.SceneGeneratorObj; NextScene: PUBLIC PROC [g: SceneGenerator] RETURNS [scene: Scene] = { IF g.currentPtr = NIL THEN RETURN[NIL]; scene _ g.currentPtr.first; g.currentPtr _ g.currentPtr.rest; }; GetCoordSysGenerator: PUBLIC PROC [scene: Scene] RETURNS [g: CoordSysGenerator] = { g _ NEW[CoordSysGeneratorObj _ [currentPtr: CoordSys.MakeListFromTree[scene.coordSysRoot]]]; }; CoordSysGenerator: TYPE = REF CoordSysGeneratorObj; CoordSysGeneratorObj: TYPE = SVScene.CoordSysGeneratorObj; NextCoordSys: PUBLIC PROC [g: CoordSysGenerator] RETURNS [cs: CoordSystem] = { IF g.currentPtr = NIL THEN RETURN[NIL]; cs _ g.currentPtr.first; g.currentPtr _ g.currentPtr.rest; }; GetListOfAssembliesFromScene: PRIVATE PROC [scene: Scene] RETURNS [aList: LIST OF Slice] = { aList _ GetListOfAssembliesFromAssembly[scene.assembly]; }; GetListOfAssembliesFromAssembly: PRIVATE PROC [assem: Slice] RETURNS [aList: LIST OF Slice] = { aList _ NIL; WITH assem.shape SELECT FROM al: SliceList => aList _ CONS[assem, GetListOfAssembliesFromAssemblyList[al]]; ENDCASE => aList _ CONS[assem, NIL]; }; GetListOfAssembliesFromAssemblyList: PRIVATE PROC [al: SliceList] RETURNS [aList: LIST OF Slice] = { aList _ NIL; FOR list: LIST OF Slice _ al.list, list.rest UNTIL list = NIL DO aList _ AppendDestructiveAssemblies[aList, GetListOfAssembliesFromAssembly[list.first]]; ENDLOOP; }; AppendDestructiveAssemblies: PRIVATE PROC [list1, list2: LIST OF Slice] RETURNS [LIST OF Slice] = { list: LIST OF Slice; IF list1 = NIL THEN RETURN [list2]; list _ list1; UNTIL list.rest = NIL DO list _ list.rest; ENDLOOP; list.rest _ list2; RETURN[list1]; }; -- end of AppendDestructiveAssemblies GetAssemblyGenerator: PUBLIC PROC [scene: Scene] RETURNS [g: AssemblyGenerator] = { aList: LIST OF Slice _ GetListOfAssembliesFromScene[scene]; g _ NEW[AssemblyGeneratorObj _ [currentPtr: aList]]; }; PrimAssembliesInScene: PUBLIC PROC [scene: Scene] RETURNS [g: AssemblyGenerator] = { aList: LIST OF Slice _ ListOfPrimAssemblies[scene.assembly, scene]; g _ NEW[AssemblyGeneratorObj _ [currentPtr: aList]]; }; AssemblyGenerator: TYPE = REF AssemblyGeneratorObj; AssemblyGeneratorObj: TYPE = SVScene.AssemblyGeneratorObj; NextAssembly: PUBLIC PROC [g: AssemblyGenerator] RETURNS [a: Slice] = { IF g.currentPtr = NIL THEN RETURN[NIL]; a _ g.currentPtr.first; g.currentPtr _ g.currentPtr.rest; }; GetLightSourceGenerator: PUBLIC PROC [scene: Scene] RETURNS [g: LightSourceGenerator] = { g _ NEW[LightSourceGeneratorObj _ [currentPtr: scene.lightSources]]; }; LightSourceGenerator: TYPE = REF LightSourceGeneratorObj; LightSourceGeneratorObj: TYPE = SVScene.LightSourceGeneratorObj; NextLight: PUBLIC PROC [g: LightSourceGenerator] RETURNS [ls: LightSource] = { IF g.currentPtr = NIL THEN RETURN[NIL]; ls _ g.currentPtr.first; g.currentPtr _ g.currentPtr.rest; }; MasterObjectsOfScene: PUBLIC PROC [scene: Scene] RETURNS [l: MasterObjectList] = { l _ scene.masterObjects; }; MasterObjectsOfAssembly: PUBLIC PROC [assembly: Slice, scene: Scene] RETURNS [l: MasterObjectList] = { primList: LIST OF Slice _ ListOfPrimAssemblies[assembly, scene]; thisMO: MasterObject; thisShape: Shape; l _ NIL; FOR list: LIST OF Slice _ primList, list.rest UNTIL list = NIL DO thisShape _ NARROW[list.first.shape]; thisMO _ thisShape.mo; l _ CONS[thisMO, l]; ENDLOOP; l _ SVScenePrivate.RemoveDuplicateMOs[l]; }; ListOfPrimAssemblies: PUBLIC PROC [assembly: Slice, scene: Scene] RETURNS [primList: LIST OF Slice] = { IF assembly = NIL THEN RETURN[NIL]; WITH assembly.shape SELECT FROM aList: SliceList => primList _ ListOfPrimAssembliesFromAssemblyList[aList.list, scene]; shape: Shape => primList _ CONS[assembly, NIL]; ENDCASE => ERROR; }; ListOfPrimAssembliesFromAssemblyList: PRIVATE PROC [aList: LIST OF Slice, scene: Scene] RETURNS [primList: LIST OF Slice] = { thisList: LIST OF Slice; IF aList = NIL THEN RETURN[NIL]; thisList _ ListOfPrimAssemblies[aList.first, scene]; IF thisList = NIL THEN primList _ ListOfPrimAssembliesFromAssemblyList[aList.rest, scene] ELSE primList _ AppendDestructiveAssemblies[thisList, ListOfPrimAssembliesFromAssemblyList[aList.rest, scene]]; }; Init: PROC = { globalDatabase _ NEW[DatabaseObj _ [scenes: NIL]]; }; Init[]; END. vSVSceneImplA.mesa Last edited by Bier on June 24, 1987 3:13:42 pm PDT Copyright c 1984 by Xerox Corporation. All rights reserved. Author: Eric Bier in July, 1982 Don't add any more to this file. It won't compile. Version Rope versionRope: PUBLIC Rope.ROPE _ "Solidviews Version 5.3 OF June 12, 1985 10:17:19 am PDT"; versionRope: PUBLIC Rope.ROPE _ "Solidviews Version 7.0 OF February 24, 1987 5:27:35 pm PST"; Used for version stamps and initial greeting. Exported to SVScene. Introduction Contents: The Solidviews System is involved with the creation and manipulation of three dimensional scenes. A scene is a list of lightsources, and a tree of assemblies. Intermediate nodes in this tree are cluster assemblies. The leaves of this tree are primitive assemblies. Each cluster assembly specifies a point set operation describing how its children should be combined. Each primitive assembly refers to a master object (a shape) and a triplet of scalars describing how this master object should be scaled before being displayed. All assemblies (cluster or primitive) refer to a coordinate system which describes how the object should be positioned and oriented with respect to its parent coordinate system (from which we can derive how it will be positioned in the scene's master coordinate system known as WORLD). Each master object is an instance of a class of shapes called a master object class. Imported Types Master Object Types Global Variables Create Entities Creates scene and adds scene to database. Includes default coordinate systems (WORLD, CAMERA, and SCENE), one default light source, five default master objects (cube, sphere, cone, cylinder, and torus) and seven default cameras (Top, Bottom, Left, Right, Front, UpLeft, and UpRight). Creates scene and adds scene to database. plane = 1, 2, 3 corresponds to the x=0, y=0, and z=0 planes respectively. plane = 4 means all three of them. ToolDatas are needed by CreatePrimitiveAssembly and CreateClusterAssembly above if the assembly is to be a tool. Must be done whenever a new scene is to be viewed (including whenever a solidviewer is created. Adding the camera to the scene tree is probably one of the first acts after creating a new coordinate system tree. A conversion from the viewer-independent to the viewer-dependent type of camera. Must be done whenever camera name (Front, Top, etc) changes (and thus whenever the scene changes). An initial list of cameras provided with a new scene (or an old scene which was made before named file cameras were introduced). topMat, bottomMat, leftMat, rightMat, frontMat, upLeftMat, upRightMat: Matrix4by4; topMat _ Matrix3d.MatMult[Matrix3d.MakeRotateXMat[90], Matrix3d.MakeTranslateMat[0,0,1800]]; bottomMat _ Matrix3d.MatMult[Matrix3d.MakeRotateXMat[-90], Matrix3d.MakeTranslateMat[0,0,1800]]; leftMat _ Matrix3d.MatMult[Matrix3d.MakeRotateYMat[-90], Matrix3d.MakeTranslateMat[0,0,1800]]; rightMat _ Matrix3d.MatMult[Matrix3d.MakeRotateYMat[90], Matrix3d.MakeTranslateMat[0,0,1800]]; frontMat _ Matrix3d.MakeTranslateMat[0,0,1800]; upLeftMat _ Matrix3d.MatMult[Matrix3d.MakeRotateYMat[-20], Matrix3d.MakeTranslateMat[0,0,1800]]; upLeftMat _ Matrix3d.MatMult[Matrix3d.MakeRotateXMat[20], upLeftMat]; upRightMat _ Matrix3d.MatMult[Matrix3d.MakeRotateYMat[20], Matrix3d.MakeTranslateMat[0,0,1800]]; upRightMat _ Matrix3d.MatMult[Matrix3d.MakeRotateXMat[20], upRightMat]; Build the Scene Tree The names of those cameras which should open automatically with the pic file is loaded are added to the scene in order. This is just a default size. It is resized below. List Append Auxiliaries For the Add Procedures A copy of List.Nconc1 for LIST OF Scene instead of LIST OF REF ANY A copy of List.Nconc1 for LightSourceList instead of LIST OF REF ANY A copy of List.Nconc1 for CoordSysList instead of LIST OF REF ANY A copy of List.Nconc1 for LIST OF Rope.ROPE instead of LIST OF REF ANY Restructure the Tree Rename this assembly and its coordinate system. Find assem's parent. Remove links from parent to assem. Create links from 'to' to assem. Likewise, assem's coordsys must now refer to the new parent's coordsys. Alter assem's coordinate system matrix so its doesn't actually move at all. Remove links from parent to assembly. Remove links from assem's coordsys to parent by pointing to new parent's CS. And update assem's coordsys's matrix so it doesn't actually move. Create link from 'to' to assem. Moves subassembly to the first position of assembly's assemblylist. Make sure "subassembly" is a subassembly of "assembly". Copies over any master objects which toScene will need to support newAssembly. Makes a copy of the newAssembly tree, adding suffix numbers to make the names unique in the new scene. Wires up the new assembly to its parent. Takes all of the assemblies from fromScene which are directly under sceneAssembly and adds them to the sceneAssembly of toScene. Makes sure that all assemblies in fromScene have names unique in toScene first. Find Scene Entities from their Names Finds the named assembly and its immediate superior. superAssembly is NIL if assembly is top level. Finds any digits on the end of the name. Looks through the scene extracting a digit and base name from each name. Finds the maximum number, adds one, reconcatenates and returns. UniqueAssemblyNameFrom: PUBLIC PROC [name: Rope.ROPE, scene: Scene] RETURNS [unique: Rope.ROPE] = { Finds any digits on the end of the name. Looks through the scene extracting a digit and base name from each name. Finds the maximum number, adds one, reconcatenates and returns. maxNum: NAT _ 0; targetBase, base: Rope.ROPE; g: AssemblyGenerator _ GetAssemblyGenerator[scene]; targetNum, num: NAT; [targetBase, targetNum] _ BaseAndNumber[name]; FOR assem: Slice _ NextAssembly[g], NextAssembly[g] UNTIL assem = NIL DO [base, num] _ BaseAndNumber[assem.name]; IF Rope.Equal[base, targetBase, TRUE] THEN maxNum _ MAX[num, maxNum]; ENDLOOP; unique _ IO.PutFR["%g.%g",[rope[targetBase]], [integer[maxNum+1]]]; }; returns found = FALSE if that is the case. Signals LightSourceNotFound if that is the case. Get Generators of Scene Entities Scene Generator CoordSystem Generator Slice Generator A pretty dumb generator. Walks the tree, makes the whole list and then feeds it to you one item at a time. LightSource Generator MasterObject Generator Get a list of the leaves of the tree and extract a master object from each. Remove duplicates. List of Primitive Assemblies Initialization Create a database. Ê#y– "Cedar" style˜Ihead– "Cedar" stylešœ™Iproc– "Cedar" stylešœ3™3Jšœ Ïmœ1™—Jšžœ˜Jšžœžœ˜Jšœ˜J˜—š ¢œžœžœ žœžœžœ˜Xš žœžœžœžœ žœžœž˜NJš žœžœžœžœžœ˜9—Jšžœ˜Jšžœžœ˜Jšœ˜—š ¢œžœžœ žœžœžœ˜aJšœ³™³Jšœžœ˜Jšœžœ˜Jšœžœ˜Jšœ7˜7šžœ5žœžœž˜IJšœ4˜4Jšžœžœžœ žœ˜E—Jšžœ˜Jšœ žœ8˜CJšœ˜J˜—– "Cedar" styleš ¢œžœžœ žœžœžœ™cJšœ³™³Jšœžœ™Jšœžœ™Jšœ3™3Jšœžœ™J™Jšœ.™.šžœ1žœ žœž™HJšœ(™(Jšžœžœžœ žœ™E—Jšžœ™Jšœ žœ8™CJšœ™—J˜J˜š ¢$œžœžœžœžœ2žœ˜¢Jšœ*™*Jšœžœ˜Jšœ˜Jšœžœ˜ Jšžœžœžœžœžœžœžœžœ˜-šžœžœž˜Jšžœ"žœžœ˜0Jšœ,žœ˜4Jšœ ˜ Jšœ ˜ —Jšžœ˜Jš žœžœžœžœžœ˜Jšœ˜—J˜š ¢#œžœžœžœžœ-˜’Jšœ0™0Jšœžœ˜Jšœ˜Jšžœžœžœžœ˜*šžœžœž˜Jšžœ"žœ˜*Jšœ,žœ˜4Jšœ ˜ Jšœ ˜ —Jšžœ˜Jšžœ˜Jšœ˜—J˜Jšœžœžœžœ˜*J˜—šœ ™ Ošœ™š¢œžœžœžœ˜>Jšœžœ:˜AJšœ˜—Jšœžœžœ˜-Jšœžœ˜4š¢ œžœžœžœ˜EJš žœžœžœžœžœ˜'Jšœ˜Jšœ!˜!Jšœ˜—Ošœ™š¢œžœžœžœ˜SJšœžœU˜\Jšœ˜—Jšœžœžœ˜3Jšœžœ ˜:š¢ œžœžœžœ˜NJš žœžœžœžœžœ˜'Jšœ˜Jšœ!˜!Jšœ˜—Ošœ™š ¢œžœžœžœ žœžœ ˜\Jšœ8˜8Jšœ˜—J˜š ¢œžœžœžœ žœžœ ˜_Jšœžœ˜ šžœ žœž˜Jšœžœ1˜NJšžœ žœžœ˜$—Jšœ˜—J˜š ¢#œžœžœžœ žœžœ ˜dJšœžœ˜ š žœžœžœžœžœž˜@JšœX˜X—Jšžœ˜Jšœ˜—J˜š¢œžœžœžœžœžœžœžœ ˜cJšœžœžœ˜Jšžœ žœžœžœ ˜#Jšœ ˜ šžœ žœž˜Jšœ˜—Jšžœ˜Jšœ˜Jšžœ˜Jšœ¡%˜(—J˜J˜š¢œžœžœžœ˜SJšœk™kJšœžœžœ-˜;Jšœžœ-˜4Jšœ˜—J˜– "Cedar" styleš¢œžœžœžœ˜TJšœžœžœ5˜CJšœžœ-˜4J– "Cedar" style˜—Jšœžœžœ˜3Jšœžœ ˜:J˜š¢ œžœžœžœ˜GJš žœžœžœžœžœ˜'Jšœ˜Jšœ!˜!Jšœ˜—Ošœ™š¢œžœžœžœ˜YJšœžœ=˜DJšœ˜—Jšœžœžœ˜9Jšœžœ#˜@š¢ œžœžœžœ˜NJš žœžœžœžœžœ˜'Jšœ˜Jšœ!˜!Jšœ˜—Ošœ™š¢œžœžœžœ˜RJšœ˜Jšœ˜J˜—š¢œžœžœ!žœ˜fJ™_Jšœ žœžœ/˜@Jšœ˜Jšœ˜Jšœžœ˜š žœžœžœžœžœž˜AJšœ žœ˜%Jšœ˜Jšœžœ ˜—Jšžœ˜Jšœ)˜)Jšœ˜—Ošœ™š ¢œžœžœ!žœ žœžœ ˜gJš žœ žœžœžœžœ˜#šžœžœž˜JšœW˜WJšœžœ žœ˜/Jšžœžœ˜—Jšœ˜—J˜š¢$œžœžœ žœžœžœ žœžœ ˜}Jšœ žœžœ˜Jš žœ žœžœžœžœ˜ Jšœ4˜4Jšžœ žœžœC˜YJšžœ1˜5Jšœ9˜9Jšœ˜——šœ™Jš¢œžœ˜šœ™Jšœžœžœ˜2Jšœ˜—J˜Jšœ˜J˜Jšžœ˜——…—jܧË