DIRECTORY CoordSys, CSG, DisplayList3d, GraphicsColor, IO, Matrix3d, Rope, Shading, SV2d, SVArtwork, SVDisplayListFiling, SVPolygon3d, SVVector3d; DisplayList3dImplA: PROGRAM IMPORTS CoordSys, DisplayList3d, GraphicsColor, IO, Matrix3d, Rope, SVArtwork, SVDisplayListFiling EXPORTS DisplayList3d, SVDisplayListFiling = BEGIN versionRope: PUBLIC Rope.ROPE _ "Solidviews Version 2.0 OF July 1, 1983 4:39 pm"; Artwork: TYPE = REF ArtworkObj; ArtworkObj: TYPE = SVArtwork.ArtworkObj; Classification: TYPE = REF ClassificationObj; ClassificationObj: TYPE = CSG.ClassificationObj; Color: TYPE = GraphicsColor.Color; CoordSysList: TYPE = CoordSys.CoordSysList; CoordSysObj: TYPE = CoordSys.CoordSysObj; CoordSystem: TYPE = REF CoordSysObj; CSGTree: TYPE = REF CSGTreeObj; CSGTreeObj: TYPE = CSG.CSGTreeObj; Matrix4by4: TYPE = Matrix3d.Matrix4by4; Point2d: TYPE = SV2d.Point2d; Point3d: TYPE = Matrix3d.Point3d; PointSetOp: TYPE = CSG.PointSetOp; -- {union, intersection, difference} Poly3d: TYPE = SVPolygon3d.Poly3d; Primitive: TYPE = REF PrimitiveObj; PrimitiveObj: TYPE = CSG.PrimitiveObj; Ray: TYPE = REF RayObj; RayObj: TYPE = CSG.RayObj; Vector: TYPE = SVVector3d.Vector; Database: TYPE = REF DatabaseObj; DatabaseObj: TYPE = DisplayList3d.DatabaseObj; Scene: TYPE = REF SceneObj; SceneObj: TYPE = DisplayList3d.SceneObj; Assembly: TYPE = REF AssemblyObj; AssemblyObj: TYPE = DisplayList3d.AssemblyObj; AssemblyList: TYPE = REF AssemblyListObj; AssemblyListObj: TYPE = DisplayList3d.AssemblyListObj; LightSource: TYPE = REF LightSourceObj; LightSourceObj: TYPE = Shading.LightSourceObj; LightSourceList: TYPE = Shading.LightSourceList; MasterObjectClass: TYPE = REF MasterObjectClassObj; MasterObjectClassObj: TYPE = DisplayList3d.MasterObjectClassObj; MasterObjectClassList: TYPE = DisplayList3d.MasterObjectClassList; FileoutProc: TYPE = DisplayList3d.FileoutProc; FileinProc: TYPE = DisplayList3d.FileinProc; MasterObject: TYPE = REF MasterObjectRec; MasterObjectRec: TYPE = DisplayList3d.MasterObjectRec; MasterObjectList: TYPE = DisplayList3d.MasterObjectList; RayCastProc: TYPE = CSG.RayCastProc; RayCastNoBBoxesProc: TYPE = CSG.RayCastNoBBoxesProc; BoundHedronProc: TYPE = DisplayList3d.BoundHedronProc; PreprocessProc: TYPE = DisplayList3d.PreprocessProc; LineDrawProc: TYPE = DisplayList3d.LineDrawProc; NormalsDrawProc: TYPE = DisplayList3d.NormalsDrawProc; CountPlanarSurfacesProc: TYPE = DisplayList3d.CountPlanarSurfacesProc; GetPlanarSurfacesProc: TYPE = DisplayList3d.GetPlanarSurfacesProc; PlanarSurface: TYPE = REF PlanarSurfaceObj; PlanarSurfaceObj: TYPE = DisplayList3d.PlanarSurfaceObj; PlanarSurfaceList: TYPE = DisplayList3d.PlanarSurfaceList; DrawPlanarSurfaceProc: TYPE = DisplayList3d.DrawPlanarSurfaceProc; DrawSubBoxesProc: TYPE = DisplayList3d.DrawSubBoxesProc; globalDatabase: Database; globalClassList: MasterObjectClassList _ NIL; globalMOList: MasterObjectList _ NIL; RegisterMasterObjectClass: PUBLIC PROC [ name: Rope.ROPE, filein: FileinProc, fileout: FileoutProc, rayCast: RayCastProc, rayCastNoBBoxes: RayCastNoBBoxesProc, getHedron: BoundHedronProc, preprocess: PreprocessProc, lineDraw: LineDrawProc, normalsDraw: NormalsDrawProc, countSurf: CountPlanarSurfacesProc, getSurf: GetPlanarSurfacesProc, drawSurf: DrawPlanarSurfaceProc, drawSubBoxes: DrawSubBoxesProc] RETURNS [moClass: MasterObjectClass] = { moClass _ NEW[MasterObjectClassObj _ [name, filein, fileout, rayCast, rayCastNoBBoxes, getHedron, preprocess, lineDraw, normalsDraw, countSurf, getSurf, drawSurf, drawSubBoxes]]; globalClassList _ AppendClassToList[moClass, globalClassList]; }; RegisterMasterObject: PUBLIC PROC [mo: MasterObject] = { globalMOList _ AppendToMasterObjects[mo, globalMOList]; }; CreateScene: PUBLIC PROC [name: Rope.ROPE] RETURNS [scene: Scene] = { initialCS: CoordSysList _ CoordSys.InitialCoordSysList[]; sceneAssemblyCS: CoordSystem; sceneAssembly: Assembly _ CreateClusterAssembly["sceneAssembly", union]; defaultRedLight: LightSource _ CreateLightSource["RedLight",[200,200,400], GraphicsColor.red]; defaultGreenLight: LightSource _ CreateLightSource["GreenLight",[-200,200,400], GraphicsColor.green]; defaultWhiteLight: LightSource _ CreateLightSource["WhiteLight",[800,800,1000],GraphicsColor.white]; scene _ NEW[SceneObj _ [ name: name, worldCS: CoordSys.FindCoordSysFromName["WORLD", initialCS], coordSystems: initialCS, lightSources: CONS[defaultWhiteLight, NIL], masterObjects: CopyMasterObjectList[globalMOList], -- Copies the list structure but not the objects. assembly: sceneAssembly, backgroundColor: GraphicsColor.white, shadows: FALSE, dirty: FALSE]]; sceneAssemblyCS _ CoordSys.CreateCoordSys["sceneAssembly", Matrix3d.Identity[], scene.worldCS]; DisplayList3d.AddCoordSysToScene[sceneAssemblyCS, scene]; scene.assembly.coordSys _ sceneAssemblyCS; globalDatabase _ AppendToDatabase[scene, globalDatabase]; }; CreateEmptyScene: PUBLIC PROC [name: Rope.ROPE] RETURNS [scene: Scene] = { scene _ NEW[SceneObj _ [name: name, worldCS: NIL, coordSystems: NIL, lightSources: NIL, masterObjects: NIL, assembly: NIL, backgroundColor: GraphicsColor.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; }; CreatePrimitiveAssembly: PUBLIC PROC [name: Rope.ROPE, object: Rope.ROPE, size: Vector, scene: Scene, artwork: Artwork _ NIL, isTool: BOOL _ FALSE] RETURNS [assembly: Assembly, masterObjectFound: BOOL] = { masterObject: MasterObject; masterObjectFound _ TRUE; [masterObject, masterObjectFound] _ FindObjectFromName[object, scene]; IF NOT masterObjectFound THEN RETURN; IF artwork = NIL THEN artwork _ SVArtwork.CreateColorArtwork[GraphicsColor.RGBToColor[.6,.6,.8], plastic]; -- light blue assembly _ NEW[AssemblyObj _ [name: name, coordSys: NIL, artwork: artwork, scalars: size, visible: TRUE, isTool: isTool, object: masterObject]]; }; CreateClusterAssembly: PUBLIC PROC [name: Rope.ROPE, pointSetOp: PointSetOp _ union, isTool: BOOL _ FALSE] RETURNS [assembly: Assembly] = { artwork: Artwork _ SVArtwork.CreateColorArtwork[GraphicsColor.IntensityToColor[1], plastic]; -- white assembly _ NEW[AssemblyObj _ [name: name, coordSys: NIL, artwork: artwork, scalars: [1,1,1], object: NEW[AssemblyListObj _ [NIL, pointSetOp] ], isTool: isTool, visible: TRUE]]; }; CreateLightSource: PUBLIC PROC [name: Rope.ROPE, position: Point3d, color: Color] RETURNS [ls: LightSource] = { vector: Vector _ position; ls _ NEW[LightSourceObj _ [name, position, color]]; }; NameAlreadyPresent: PUBLIC SAFE SIGNAL = CODE; AddMasterObjectToScene: PUBLIC PROC [mo: MasterObject, scene: Scene] = { IF ObjectNameIsPresent[mo.name, scene] THEN SIGNAL NameAlreadyPresent; scene.masterObjects _ 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]; }; AddCoordSysToScene: PUBLIC PROC [cs: CoordSystem, scene: Scene] = { IF CoordSysNameIsPresent[cs.name, scene] THEN SIGNAL NameAlreadyPresent; scene.coordSystems _ AppendToCoordSystems[cs, scene.coordSystems]; }; AddAssemblyToScene: PUBLIC PROC [assembly: Assembly, scene: Scene, mat: Matrix4by4] = { cs: CoordSystem _ CoordSys.CreateCoordSys[assembly.name, mat, scene.assembly.coordSys]; AddCoordSysToScene[cs, scene]; assembly.coordSys _ cs; scene.assembly.object _ AppendToAssemblyList[assembly, NARROW[scene.assembly.object]]; }; AddSubassemblyToAssembly: PUBLIC PROC [subassembly: Assembly, assembly: Assembly, scene: Scene, mat: Matrix4by4] = { SELECT TRUE FROM ISTYPE[assembly.object,AssemblyList] => { -- add to old AssemblyList alist: AssemblyList _ NARROW[assembly.object]; cs: CoordSystem _ CoordSys.CreateCoordSys[subassembly.name, mat, assembly.coordSys]; AddCoordSysToScene[cs, scene]; subassembly.coordSys _ cs; alist _ AppendToAssemblyList[subassembly, alist]}; ENDCASE => SIGNAL AttemptToAddSubassemblyToPrimitive; }; AttemptToAddSubassemblyToPrimitive: PUBLIC SIGNAL = CODE; AddSubassemblyToAssemblyWithCS: PUBLIC PROC [subassembly: Assembly, assembly: Assembly, scene: Scene, coordSys: CoordSystem] = { SELECT TRUE FROM ISTYPE[assembly.object,AssemblyList] => { -- add to old AssemblyList alist: AssemblyList _ NARROW[assembly.object]; coordSys.withRespectTo _ assembly.coordSys; AddCoordSysToScene[coordSys, scene]; subassembly.coordSys _ coordSys; alist _ AppendToAssemblyList[subassembly, alist]}; ENDCASE => SIGNAL AttemptToAddSubassemblyToPrimitive; }; RenameAssembly: PUBLIC PROC [assem: Assembly, newName: Rope.ROPE, scene: Scene] = { -- rename this assembly and its coordinate system assem.name _ newName; assem.coordSys.name _ newName; }; CopyAssemblyAndSons: PUBLIC PROC [assembly: Assembly, scene: Scene, prefix: Rope.ROPE] RETURNS [copy: Assembly] = { moFound: BOOL; IF NewNamesAlreadyPresent[assembly, scene, prefix] THEN SIGNAL NameAlreadyPresent; WITH assembly.object SELECT FROM alist: AssemblyList => {-- assembly is a composite assembly. copy _ CreateClusterAssembly[Rope.Concat[prefix, assembly.name], alist.pointSetOp]; copy.coordSys _ CoordSys.CreateCoordSys[name: copy.name, mat: Matrix3d.Identity[], withRespectTo: NIL]; CopySubassemblies[copy, alist, scene, prefix]; }; mo: MasterObject => { -- assembly is a primitive assembly artworkCopy: Artwork _ SVArtwork.Copy[assembly.artwork]; [copy, moFound] _ CreatePrimitiveAssembly[Rope.Concat[prefix, assembly.name], mo.name, assembly.scalars, scene, artworkCopy, assembly.isTool]; IF NOT moFound THEN ERROR; -- for some reason the master object which assembly refers to is not registered in the scene (report this to SolidviewsSupport). copy.coordSys _ CoordSys.CreateCoordSys[name: copy.name, mat: Matrix3d.Identity[], withRespectTo: NIL]; }; ENDCASE => ERROR; }; -- end of CopyAssemblyAndSons CopyAssemblyAndSonsUsingNewSceneMOs: PUBLIC PROC [assembly: Assembly, newScene: Scene] RETURNS [copy: Assembly] = { moFound: BOOL; IF AnyNamesAlreadyPresent[assembly, newScene] THEN SIGNAL NameAlreadyPresent; WITH assembly.object SELECT FROM alist: AssemblyList => {-- assembly is a composite assembly. copy _ CreateClusterAssembly[assembly.name, alist.pointSetOp]; copy.coordSys _ CoordSys.CreateCoordSys[name: copy.name, mat: Matrix3d.Identity[], withRespectTo: NIL]; CopySubassembliesUsingNewMOs[copy, alist, newScene]; }; mo: MasterObject => { -- assembly is a primitive assembly artworkCopy: Artwork _ SVArtwork.Copy[assembly.artwork]; [copy, moFound] _ CreatePrimitiveAssembly[assembly.name, mo.name, assembly.scalars, newScene, artworkCopy, assembly.isTool]; IF NOT moFound THEN ERROR; -- for some reason the master object which assembly refers to is not registered in the scene (report this to SolidviewsSupport). copy.coordSys _ CoordSys.CreateCoordSys[name: copy.name, mat: Matrix3d.Identity[], withRespectTo: NIL]; }; ENDCASE => ERROR; }; -- end of CopyAssemblyAndSonsUsingNewSceneMOs CopySubassemblies: PRIVATE PROC [assembly: Assembly, alist: AssemblyList, scene: Scene, prefix: Rope.ROPE] = { thisA: Assembly; FOR list: LIST OF Assembly _ alist.list, list.rest UNTIL list = NIL DO thisA _ CopyAssemblyAndSons[list.first, scene, prefix]; thisA.coordSys.mat _ list.first.coordSys.mat; AddSubassemblyToAssemblyWithCS[thisA, assembly, scene, thisA.coordSys]; ENDLOOP; }; CopySubassembliesUsingNewMOs: PRIVATE PROC [assembly: Assembly, alist: AssemblyList, newScene: Scene] = { thisA: Assembly; FOR list: LIST OF Assembly _ alist.list, list.rest UNTIL list = NIL DO thisA _ CopyAssemblyAndSonsUsingNewSceneMOs[list.first, newScene]; thisA.coordSys.mat _ list.first.coordSys.mat; AddSubassemblyToAssemblyWithCS[thisA, assembly, newScene, thisA.coordSys]; ENDLOOP; }; MoveSubassembly: PUBLIC PROC [assem: Assembly, to: Assembly, scene: Scene] = { assemWithSameName, parent: Assembly; parentList: AssemblyList; found: BOOL; toCS: CoordSystem _ to.coordSys; [assemWithSameName, parent] _ FindAssemblyFromName[assem.name, scene]; IF assemWithSameName # assem THEN ERROR; IF NOT(ISTYPE [to.object, AssemblyList] OR to.object = NIL) THEN SIGNAL AttemptToAddSubassemblyToPrimitive; parentList _ NARROW[parent.object]; [parent.object, found] _ TemporaryRemoveFromAssemblyList[assem, parentList, scene]; IF NOT found THEN ERROR; -- it was found just a few lines ago. What happened? [] _ CoordSys.TPutAinTermsOfB[assem.coordSys, to.coordSys]; to.object _ AppendToAssemblyList[assem, NARROW[to.object]] }; -- end of MoveSubassembly MoveToFrontOfAssembly: PUBLIC PROC [subassembly: Assembly, assembly: Assembly, scene: Scene] = { aList: AssemblyList _ NARROW[assembly.object]; success: BOOL _ FALSE; FOR list: LIST OF Assembly _ aList.list, list.rest UNTIL list = NIL DO IF list.first = subassembly THEN success_TRUE; ENDLOOP; IF NOT success THEN ERROR SubassemblyNotFound; [aList, success] _ TemporaryRemoveFromAssemblyList[subassembly, aList, scene]; IF NOT success THEN ERROR SubassemblyNotFound; aList.list _ CONS[subassembly, aList.list]; }; SubassemblyNotFound: PUBLIC ERROR = CODE; AddMOsToScene: PRIVATE PROC [moList: MasterObjectList, scene: Scene] = { FOR list: MasterObjectList _ moList, list.rest UNTIL list = NIL DO scene.masterObjects _ AppendToMasterObjects[list.first, scene.masterObjects]; ENDLOOP; }; CopyMOList: PRIVATE PROC [moList: MasterObjectList] RETURNS [copyList: MasterObjectList] = { copyList _ NIL; FOR list: MasterObjectList _ moList, list.rest UNTIL list = NIL DO copyList _ AppendToMasterObjects[CopyMasterObject[list.first], copyList]; ENDLOOP; }; MergeAssemblyIntoScene: PUBLIC PROC [newAssembly: Assembly, fromScene: Scene, parentAssembly: Assembly, toScene: Scene] RETURNS [copyAssembly: Assembly] = { moList: MasterObjectList _ MasterObjectsOfAssembly[newAssembly, fromScene]; toMoList: MasterObjectList _ MasterObjectsOfScene[toScene]; neededList: MasterObjectList _ MoListMinusMoList[moList, toMoList]; neededList _ CopyMOList[neededList]; AddMOsToScene[neededList, toScene]; copyAssembly _ CopyAssemblyAndSonsUsingNewSceneMOs [assembly: newAssembly, newScene: toScene]; copyAssembly.coordSys.mat _ newAssembly.coordSys.mat; SVDisplayListFiling.AddSubassemblyToAssemblyWithCS[copyAssembly, parentAssembly, toScene, copyAssembly.coordSys]; }; MergeSceneIntoScene: PUBLIC PROC [fromScene: Scene, toScene: Scene] RETURNS [success: BOOL] = { fromList: AssemblyList _ NARROW[fromScene.assembly.object]; fromScene.assembly.name _ Rope.Concat[fromScene.name, "SceneAssembly"]; IF AnyNamesAlreadyPresent[fromScene.assembly, toScene] THEN RETURN[FALSE]; AddCoordSystemsInAssemblyToScene[fromScene.assembly, toScene]; FOR list: LIST OF Assembly _ fromList.list, list.rest UNTIL list = NIL DO AddSubassemblyToAssemblyWithCS [subassembly: list.first, assembly: toScene.assembly, scene: toScene, coordSys: list.first.coordSys]; ENDLOOP; }; AddCoordSystemsInAssemblyToScene: PRIVATE PROC [assembly: Assembly, scene: Scene] = { WITH assembly.object SELECT FROM alist: AssemblyList => { AddCoordSysToScene[assembly.coordSys, scene]; AddCoordSystemsInAssemblyListToScene[alist, scene]; }; mo: MasterObject => AddCoordSysToScene[assembly.coordSys, scene]; ENDCASE => ERROR; }; AddCoordSystemsInAssemblyListToScene: PRIVATE PROC [assemblyList: AssemblyList, scene: Scene] = { FOR list: LIST OF Assembly _ assemblyList.list, list.rest UNTIL list = NIL DO AddCoordSystemsInAssemblyToScene[list.first, scene]; ENDLOOP; }; SetArtworkAssembly: PUBLIC PROC [assembly: Assembly, artwork: Artwork, scene: Scene] = { FOR list: LIST OF Assembly _ ListOfPrimAssemblies[assembly, scene], list.rest UNTIL list = NIL DO list.first.artwork _ artwork; ENDLOOP; }; DeleteMasterObjectNamed: PUBLIC PROC [moName: Rope.ROPE, scene: Scene] RETURNS [found: BOOL] = { mo, beforeMo, afterMo: MasterObjectList; [beforeMo, mo, afterMo, found] _ FindMasterObjectAndNeighborsFromName[moName, scene.masterObjects]; IF NOT found THEN RETURN; IF beforeMo = NIL THEN scene.masterObjects _ afterMo ELSE beforeMo.rest _ afterMo; }; -- end of DeleteMasterObjectNamed DeleteMasterObjectIfUnused: PUBLIC PROC [mo: MasterObject, scene: Scene] RETURNS [found: BOOL] = { IF Rope.Equal[mo.class.name, "sphere"] OR Rope.Equal[mo.class.name, "block"] OR Rope.Equal[mo.class.name, "cylinder"] OR Rope.Equal[mo.class.name, "cone"] THEN RETURN[TRUE]; FOR primitiveAssemblies: LIST OF Assembly _ ListOfPrimAssemblies[scene.assembly, scene], primitiveAssemblies.rest UNTIL primitiveAssemblies = NIL DO IF primitiveAssemblies.first.object = mo THEN RETURN[TRUE]; ENDLOOP; found _ DeleteMasterObjectNamed[mo.name, scene]; }; -- end of DeleteMasterObjectIfUnused DeleteCoordSysNamed: PUBLIC PROC [csName: Rope.ROPE, scene: Scene] = { cs, beforeCS, afterCS: CoordSysList; notFound: BOOL _ FALSE; [beforeCS, cs, afterCS] _ CoordSys.FindCoordSysAndNeighborsFromName[csName, scene.coordSystems !CoordSys.CoordSysNotFound => {notFound _ TRUE; CONTINUE}]; IF notFound THEN RETURN; IF beforeCS = NIL THEN scene.coordSystems _ afterCS ELSE beforeCS.rest _ afterCS; }; -- end of DeleteCoordSysNamed DeleteLightSourceNamed: PUBLIC PROC [lsName: Rope.ROPE, scene: Scene] = { ls, beforeLS, afterLS: LightSourceList; notFound: BOOL _ FALSE; [beforeLS, ls, afterLS] _ FindLightSourceAndNeighborsFromName[lsName, scene.lightSources !LightSourceNotFound => {notFound _ TRUE; CONTINUE}]; IF notFound THEN RETURN; IF beforeLS = NIL THEN scene.lightSources _ afterLS ELSE beforeLS.rest _ afterLS; }; -- end of DeleteLightSourceNamed ClearScene: PUBLIC PROC [scene: Scene] = { scene.assembly.object _ NEW[AssemblyListObj _ [NIL, union] ]; ClearCoordSystems[scene]; ClearMasterObjects[scene]; }; ClearCoordSystems: PUBLIC PROC [scene: Scene] = { -- removes all but WORLD, SCREEN and sceneAssembly -- assumes for now that WORLD, and SCREEN are the first 2 coordsystems on the list z: CoordSysList _ scene.coordSystems; -- WORLD z _ z.rest; -- SCREEN z _ z.rest; -- sceneAssembly z.rest _ NIL; -- cut off the rest }; ClearMasterObjects: PUBLIC PROC [scene: Scene] = { z: MasterObjectList _ scene.masterObjects; -- "sphere" z _ z.rest; -- "block" z _ z.rest; -- "cone" z _ z.rest; -- "cylinder" z.rest _ NIL; -- cut off the rest }; DeleteSubassemblyFromAssembly: PUBLIC PROC [subassembly: Assembly, assembly: Assembly, scene: Scene] RETURNS [success: BOOL] = { IF ISTYPE[assembly.object,AssemblyList] THEN [assembly.object, success] _ RemoveFromAssemblyList[subassembly, NARROW[assembly.object,AssemblyList], scene] ELSE ERROR; }; RemoveFromAssemblyList: PRIVATE PROC [a: Assembly, al: AssemblyList, scene: Scene] RETURNS [newAl: AssemblyList, success: BOOL] = { lastAssemblyList: LIST OF Assembly _ al.list; IF lastAssemblyList.first = a THEN {-- first item on the list DeleteAssemblyAndSons[a, scene]; al.list _ lastAssemblyList.rest; RETURN[al, TRUE] }; FOR l: LIST OF Assembly _ lastAssemblyList.rest, l.rest UNTIL l = NIL DO IF l.first = a THEN { DeleteAssemblyAndSons[a, scene]; success _ TRUE; lastAssemblyList.rest _ l.rest; -- splice out a newAl _ al; RETURN; } ELSE lastAssemblyList _ lastAssemblyList.rest; ENDLOOP; success _ FALSE; }; TemporaryRemoveFromAssemblyList: PRIVATE PROC [a: Assembly, al: AssemblyList, scene: Scene] RETURNS [newAl: AssemblyList, success: BOOL] = { lastAssemblyList: LIST OF Assembly _ al.list; IF lastAssemblyList.first = a THEN {-- first item on the list al.list _ lastAssemblyList.rest; RETURN[al, TRUE] }; FOR l: LIST OF Assembly _ lastAssemblyList.rest, l.rest UNTIL l = NIL DO IF l.first = a THEN { success _ TRUE; lastAssemblyList.rest _ l.rest; -- splice out a newAl _ al; RETURN; } ELSE lastAssemblyList _ lastAssemblyList.rest; ENDLOOP; success _ FALSE; }; DeleteAssemblyAndSons: PRIVATE PROC [a: Assembly, scene: Scene] = { DeleteCoordSysNamed[a.coordSys.name, scene]; WITH a.object SELECT FROM alist: AssemblyList => DeleteAssemblyListAndSons[alist, scene]; mo: MasterObject => RETURN; ENDCASE => ERROR; }; DeleteAssemblyListAndSons: PRIVATE PROC [alist: AssemblyList, scene: Scene] = { FOR list: LIST OF Assembly _ alist.list, list.rest UNTIL list = NIL DO DeleteAssemblyAndSons[list.first, scene]; 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: Assembly, superAssembly: Assembly] = { t: Assembly _ scene.assembly; success: BOOL; [assembly, superAssembly, success] _ FindAssemblyInTree[name, t, NIL]; IF success = FALSE THEN SIGNAL AssemblyNotFound; }; AssemblyNotFound: PUBLIC SIGNAL = CODE; AssemblyNameIsPresent: PUBLIC PROC [name: Rope.ROPE, scene: Scene] RETURNS [BOOL] = { dummy1, dummy2: Assembly; isPresent: BOOL; [dummy1, dummy2, isPresent] _ FindAssemblyInTree[name, scene.assembly, NIL]; RETURN[isPresent]; }; FindAssemblyInTree: PRIVATE PROC [name: Rope.ROPE, t: Assembly, super: Assembly] RETURNS [assembly: Assembly, superAssembly: Assembly, success: BOOL] = { IF t = NIL THEN RETURN[NIL,NIL,FALSE]; IF Rope.Equal[t.name, name] THEN RETURN[t, super, TRUE]; WITH t.object SELECT FROM as: AssemblyList => { FOR l: LIST OF Assembly _ 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: Assembly, scene: Scene] RETURNS [BOOL] = { IF AssemblyNameIsPresent[assembly.name, scene] THEN RETURN [TRUE]; WITH assembly.object SELECT FROM mo: MasterObject => RETURN[FALSE]; aList: AssemblyList => RETURN[AnyNamesAlreadyPresentInList[aList, scene]]; ENDCASE => RETURN[FALSE]; }; AnyNamesAlreadyPresentInList: PRIVATE PROC [assemblyList: AssemblyList, scene: Scene] RETURNS [BOOL] = { FOR list: LIST OF Assembly _ assemblyList.list, list.rest UNTIL list = NIL DO IF AnyNamesAlreadyPresent[list.first, scene] THEN RETURN [TRUE]; ENDLOOP; RETURN [FALSE]; }; NewNamesAlreadyPresent: PUBLIC PROC [assembly: Assembly, scene: Scene, prefix: Rope.ROPE] RETURNS [BOOL] = { newName: Rope.ROPE _ Rope.Concat[prefix, assembly.name]; IF AssemblyNameIsPresent[newName, scene] THEN RETURN [TRUE]; WITH assembly.object SELECT FROM mo: MasterObject => RETURN[FALSE]; aList: AssemblyList => RETURN[NewNamesAlreadyPresentInList[aList, scene, prefix]]; ENDCASE => RETURN[FALSE]; }; NewNamesAlreadyPresentInList: PRIVATE PROC [assemblyList: AssemblyList, scene: Scene, prefix: Rope.ROPE] RETURNS [BOOL] = { FOR list: LIST OF Assembly _ assemblyList.list, list.rest UNTIL list = NIL DO IF NewNamesAlreadyPresent[list.first, scene, prefix] THEN RETURN [TRUE]; ENDLOOP; RETURN [FALSE]; }; FindClassFromName: PUBLIC PROC [name: Rope.ROPE] RETURNS [moClass: MasterObjectClass, success: BOOL] = { FOR moClassList: MasterObjectClassList _ globalClassList, moClassList.rest UNTIL moClassList = NIL DO IF Rope.Equal[moClassList.first.name, name, TRUE] THEN RETURN [moClassList.first, TRUE]; ENDLOOP; RETURN[NIL, 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]; }; 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]; }; CoordSysNameIsPresent: PUBLIC PROC [name: Rope.ROPE, scene: Scene] RETURNS [BOOL] = { FOR cl: CoordSysList _ scene.coordSystems, cl.rest UNTIL cl = NIL DO IF Rope.Equal[cl.first.name, name, TRUE] THEN RETURN [TRUE]; ENDLOOP; RETURN[FALSE]; }; 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]; }; UniqueNameFrom: 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; uniqueStream: IO.STREAM; targetBase, base: Rope.ROPE; targetNum, num: NAT; [targetBase, targetNum] _ BaseAndNumber[name]; FOR ol: MasterObjectList _ scene.masterObjects, ol.rest UNTIL ol = NIL DO [base, num] _ BaseAndNumber[ol.first.name]; IF Rope.Equal[base, targetBase, TRUE] THEN maxNum _ Max[num, maxNum]; ENDLOOP; uniqueStream _ IO.CreateOutputStreamToRope[]; uniqueStream.PutF["%g.%g",[rope[targetBase]], [integer[maxNum+1]]]; unique _ IO.GetOutputStreamRope[uniqueStream]; }; Max: PRIVATE PROC [a, b: NAT] RETURNS [NAT] = { RETURN[IF a > b THEN a ELSE b]; }; BaseAndNumber: PRIVATE PROC [name: Rope.ROPE] RETURNS [base: Rope.ROPE, number: NAT] = { noNumber: BOOL _ FALSE; nameStream: IO.STREAM; next: CHAR; nameStream _ IO.CreateInputStreamFromRope[name]; base _ ReadAlpha[nameStream]; next _ nameStream.GetChar[ !IO.EndOfStream => {noNumber _ TRUE; CONTINUE}]; IF noNumber THEN number _ 0 ELSE IF next = '. THEN number _ IO.GetInt[nameStream] ELSE number _ 0; }; ReadAlpha: PRIVATE PROC [s: IO.STREAM] RETURNS [base: Rope.ROPE] = { base _ IO.GetToken[s, AlphaBreakProc]; }; AlphaBreakProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = TRUSTED { RETURN[IF char = '. THEN break ELSE other] }; FindMasterObjectAndNeighborsFromName: PRIVATE PROC [moName: Rope.ROPE, moList: MasterObjectList] RETURNS [beforeMo, mo, afterMo: MasterObjectList, found: BOOL] = { -- returns found = FALSE if that is the case. 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] THEN { beforeMo _ lastL; mo _ l; afterMo _ l.rest; RETURN}; lastL _ l; l _ l.rest; ENDLOOP; RETURN[NIL, NIL, NIL, FALSE]; }; FindLightSourceAndNeighborsFromName: PRIVATE PROC [lsName: Rope.ROPE, lsList: LightSourceList] RETURNS [beforeLS, ls, afterLS: LightSourceList] = { -- signals LightSourceNotFound if that is the case. 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: SIGNAL = CODE; AppendToDatabase: PROC [scene: Scene, database: Database] RETURNS [Database] = { -- a copy of List.Nconc1 for LIST OF Scene instead of LIST OF REF ANY 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]; }; AppendToAssemblyList: PROC [assembly: Assembly, list: AssemblyList] RETURNS [AssemblyList] = { -- a copy of List.Nconc1 for LIST OF Assembly instead of LIST OF REF ANY z: LIST OF Assembly _ list.list; IF z = NIL THEN {list.list _ CONS[assembly, NIL]; RETURN[list]}; UNTIL z.rest = NIL DO z _ z.rest; ENDLOOP; z.rest _ CONS[assembly,NIL]; RETURN[list]; }; AppendToLightSourceList: PROC [ls: LightSource, list: LightSourceList] RETURNS [LightSourceList] = { -- a copy of List.Nconc1 for LightSourceList instead of LIST OF REF ANY 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]; }; AppendToCoordSystems: PROC [cs: CoordSystem, list: CoordSysList] RETURNS [CoordSysList] = { -- a copy of List.Nconc1 for CoordSysList instead of LIST OF REF ANY z: CoordSysList _ list; IF z = NIL THEN RETURN[CONS[cs,NIL]]; UNTIL z.rest = NIL DO z _ z.rest; ENDLOOP; z.rest _ CONS[cs,NIL]; RETURN[list]; }; AppendToMasterObjects: PROC [mo: MasterObject, list: MasterObjectList] RETURNS [MasterObjectList] = { -- a copy of List.Nconc1 for MasterObjectList instead of LIST OF REF ANY z: MasterObjectList _ list; IF z = NIL THEN RETURN[CONS[mo,NIL]]; UNTIL z.rest = NIL DO z _ z.rest; ENDLOOP; z.rest _ CONS[mo,NIL]; RETURN[list]; }; AppendClassToList: PROC [moc: MasterObjectClass, list: MasterObjectClassList] RETURNS [MasterObjectClassList] = { -- a copy of List.Nconc1 for MasterObjectClassList instead of LIST OF REF ANY z: MasterObjectClassList _ list; IF z = NIL THEN RETURN[CONS[moc,NIL]]; UNTIL z.rest = NIL DO z _ z.rest; ENDLOOP; z.rest _ CONS[moc,NIL]; RETURN[list]; }; GetSceneGenerator: PUBLIC PROC RETURNS [g: SceneGenerator] = { g _ NEW[SceneGeneratorObj _ [currentPtr: globalDatabase.scenes]]; }; SceneGenerator: TYPE = REF SceneGeneratorObj; SceneGeneratorObj: TYPE = DisplayList3d.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: scene.coordSystems]]; }; CoordSysGenerator: TYPE = REF CoordSysGeneratorObj; CoordSysGeneratorObj: TYPE = DisplayList3d.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 Assembly] = { aList _ GetListOfAssembliesFromAssembly[scene.assembly]; }; GetListOfAssembliesFromAssembly: PRIVATE PROC [assem: Assembly] RETURNS [aList: LIST OF Assembly] = { aList _ NIL; WITH assem.object SELECT FROM al: AssemblyList => aList _ CONS[assem, GetListOfAssembliesFromAssemblyList[al]]; ENDCASE => aList _ CONS[assem, NIL]; }; GetListOfAssembliesFromAssemblyList: PRIVATE PROC [al: AssemblyList] RETURNS [aList: LIST OF Assembly] = { aList _ NIL; FOR list: LIST OF Assembly _ al.list, list.rest UNTIL list = NIL DO aList _ AppendDestructiveAssemblies[aList, GetListOfAssembliesFromAssembly[list.first]]; ENDLOOP; }; AppendDestructiveAssemblies: PRIVATE PROC [list1, list2: LIST OF Assembly] RETURNS [LIST OF Assembly] = { list: LIST OF Assembly; 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] = { -- a pretty dumb generator. Walks the tree, makes the whole list and then feeds it to you one item at a time. aList: LIST OF Assembly _ GetListOfAssembliesFromScene[scene]; g _ NEW[AssemblyGeneratorObj _ [currentPtr: aList]]; }; AssemblyGenerator: TYPE = REF AssemblyGeneratorObj; AssemblyGeneratorObj: TYPE = DisplayList3d.AssemblyGeneratorObj; NextAssembly: PUBLIC PROC [g: AssemblyGenerator] RETURNS [a: Assembly] = { 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 = DisplayList3d.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: Assembly, scene: Scene] RETURNS [l: MasterObjectList] = { primList: LIST OF Assembly _ ListOfPrimAssemblies[assembly, scene]; thisMO: MasterObject; l _ NIL; FOR list: LIST OF Assembly _ primList, list.rest UNTIL list = NIL DO thisMO _ NARROW[list.first.object]; l _ CONS[thisMO, l]; ENDLOOP; l _ RemoveDuplicateMOs[l]; }; ListOfPrimAssemblies: PUBLIC PROC [assembly: Assembly, scene: Scene] RETURNS [primList: LIST OF Assembly] = { IF assembly = NIL THEN RETURN[NIL]; WITH assembly.object SELECT FROM aList: AssemblyList => primList _ ListOfPrimAssembliesFromAssemblyList[aList.list, scene]; mo: MasterObject => primList _ CONS[assembly, NIL]; ENDCASE => ERROR; }; ListOfPrimAssembliesFromAssemblyList: PRIVATE PROC [aList: LIST OF Assembly, scene: Scene] RETURNS [primList: LIST OF Assembly] = { thisList: LIST OF Assembly; 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]]; }; RemoveDuplicateMOs: PRIVATE PROC [moList: MasterObjectList] RETURNS [uniqueList: MasterObjectList] = { thisMO: MasterObject; uniqueList _ NIL; FOR list: MasterObjectList _ moList, list.rest UNTIL list = NIL DO thisMO _ list.first; IF NOT ObjectNameInList[thisMO.name, uniqueList] THEN uniqueList _ CONS[thisMO, uniqueList]; ENDLOOP; }; ObjectNameInList: PRIVATE PROC [moName: Rope.ROPE, moList: MasterObjectList] RETURNS [BOOL]= { FOR list: MasterObjectList _ moList, list.rest UNTIL list = NIL DO IF Rope.Equal[list.first.name, moName, TRUE] THEN RETURN[TRUE]; ENDLOOP; RETURN[FALSE]; }; MoListMinusMoList: PRIVATE PROC [moList1, moList2: MasterObjectList] RETURNS [moList1MinusmoList2: MasterObjectList] = { moList1MinusmoList2 _ NIL; FOR list: MasterObjectList _ moList1, list.rest UNTIL list = NIL DO IF NOT ObjectNameInList[list.first.name, moList2] THEN moList1MinusmoList2 _ CONS[list.first, moList1MinusmoList2]; ENDLOOP; }; CopyMasterObjectList: PRIVATE PROC [moList: MasterObjectList] RETURNS [copy: MasterObjectList] = { copy _ NIL; FOR list: MasterObjectList _ moList, list.rest UNTIL list = NIL DO copy _ AppendToMasterObjects[list.first, copy]; ENDLOOP; }; Init: PROC = { globalDatabase _ NEW[DatabaseObj _ [scenes: NIL]]; }; Init[]; END. ØDisplayList3dImplA.mesa Last edited by Bier on July 6, 1983 3:59 pm Author: Eric Bier in July, 1982 Used for version stamps and initial greeting. Exported by DisplayList3dImpl. 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 DisplayList Types Databases, Scenes, Assemblies, and Lightsources Master Object Class Types Master Object Types Global Variables Set Up the System Create Entities Creates scene and adds scene to database. Creates scene and adds scene to database. Adds the named object to the scene's master object list Calculate vector from position as follows: LightSources are positioned in WORLD coordinates. Assume that objects will be placed near the origin of this coordinate system. Hence the position is also the vector from the objects to the lightsource. Build the Scene Tree Add assembly to the top level list of assemblies in the current scene Automatically makes coordsys of subassembly refer to coordsys of super assembly. Restructure the Tree CopyAssemblyAndSons returns an assembly which has a coordinate system whose mat and withRespectTo are null. We must fill in the mat manually. AddSubassemblyToAssembly will fill in the withRespectTo automatically. assembly.coordSys must exist at this point. CopySubassembliesUsingNewMOs returns an assembly which has a coordinate system whose mat and withRespectTo are null. We must fill in the mat manually. AddSubassemblyToAssembly will fill in the withRespectTo automatically. assembly.coordSys must exist at this point. 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". We assume that none of the mo's in moList is already in scene Makes a list of all of the masterobjects needed. Compares this list to the list of masterobjects available in the new scene, subtracting any that are available. Copies those that are still needed and adds them to the new scene. Makes a copy of the newAssembly tree (without changing names) but refering to master objects 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. This currently destroys fromScene. Delete Parts of the Scene Tree For now, we won't delete the built-in instances Removes all but "block", "sphere", "cone", and "cylinder" from current scene. Assumes for now that "sphere","cone", and "cylinder", and "block" are the first five master objects. Tree walk through the assembly deleting all of its coordinate systems. Then, cut the assembly loose and feed it to the garbage collector. A simple list remove operation. Not break up the assembly and its sons, nor does it delete their coordinate systems. This routine is called by MoveToFrontOfAssembly to splice an assembly out of an AssemblyList Find Scene Entities from their Names Finds the named assembly and its immediate superior. superAssembly is NIL if assembly is top level. List Append Auxiliaries For the Add Procedures Get Generators of Scene Entities Scene Generator CoordSystem Generator Assembly Generator 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 Other List Auxiliaries Removing Duplicates **** Naive algorithm for now. Go through moList. Add anything to uniqueList which it doesn't already have Find all elements of moList1 which are not in moList2 Currently this has O[n2] behavior. Since moList typically has 4 elements, this is alright. Improve if moList grows. Initialization Create a database. Ê!y– "Cedar" style˜Ihead1– "Cedar" stylešœ™Iproc– "Cedar" stylešœ+™+šœ ™ – "Cedar" styleš Ïk œ œœœœ]œ'˜ÐLš˜šœQ˜QIbodyšœM™M——šœ ™ M– "Cedar" stylešœdÐbiœž œž œ'žÏiž œž Ÿž œ%žœVž œ¡žœžœ™’——šœ™Jšœ œœ ˜Jšœ œ˜(Jšœœœ˜-Jšœœœ˜0Jšœœ˜"Jšœœ˜+Jšœ œ˜)Jšœ œœ ˜$Jšœ œœ ˜Jšœ œœ ˜"Jšœ œ˜'Jšœ œ˜Jšœ œ˜!Jšœ œœ1˜GJšœœ˜"Jšœ œœ˜#Jšœœœ˜&Jšœœœ˜Jšœœœ˜Jšœœ˜!—šœ™Ihead2šœ/™/Jšœ œœ ˜!Jšœ œ˜/Jšœœœ ˜Jšœ œ˜)Jšœ œœ ˜!Jšœ œ˜.Jšœœœ˜)Jšœœ"˜7Jšœ œœ˜'Jšœœ˜.Jšœœ˜0Nšœ™Jšœœœ˜3Jšœœ&˜@Jšœœ(˜CJšœ œ˜.Jšœ œ˜,Nšœ™Jšœœœ˜)Jšœœ!˜6Jšœœ#˜9Jšœ œœ ˜$Jšœœœ˜4Jšœœ!˜6Jšœœ ˜4Jšœœ˜0Jšœœ!˜6Jšœœ)˜Fšœœ'˜BJšœœœ˜+Jšœœ"˜8Jšœœ#˜:—Jšœœ'˜BJšœœ"˜8—šœ™Jšœ˜Jšœ)œ˜-Jšœ!œ˜%Kšœ™šÏnœœœ˜(JšÏbœœ˜Jš¡œ ˜Jš¡œ˜Jš¡œ˜Jš¡œ˜%Jš¡ œ˜Jš¡ œ˜Jš¡œ˜Jš¡ œ˜Jš¡ œ˜#Jš¡œ˜Jš¡œ˜ Jš¡ œ˜—Jšœ!˜(Jšœ œé˜÷J˜Jš œœœT˜u—šœ™š   œœœ œœ˜EJšœ)™)Jšœ9˜9Jšœ˜JšœH˜HJšœ^˜^Jšœe˜eJšœd˜dšœœ ˜Jšœ ˜ Jšœ;˜;Jšœ˜Jšœœœ˜+Jšœ3Ïc1˜dJšœ˜Jšœ%˜%Jšœ œ˜Jšœœ˜—Jšœ_˜_Jšœ9˜9Jšœ*˜*Jšœ9˜9Jšœ˜—š  œœœ œœ˜JJšœ)™)šœœ˜#Jšœ œ˜ Jšœœœ˜%Jšœœ˜Jšœ œ˜Jšœ%˜%Jšœ œ˜Jšœœ˜—Jšœ9˜9Jšœ˜—š œ œ˜!Jš¡œœ˜Jš¡œ˜Jš¡œœœ˜Jš¡œœœ˜Jš¡ œœœ˜š¡ œœœœ˜4Jšœ7™7—Jšœœ˜Jšœ;˜;Jšœ˜—š œœœœ˜QJšœœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ"˜"Jšœ˜—Jš œœœ œœ1œ œœ˜“šœ)œ˜9Jšœ˜Jšœœ˜JšœF˜FJšœœœœ˜%Jšœ œœ ˜JšœK¢ ˜XJšœ œ˜Jšœœ,œ)˜sJšœ˜—š œœœ œ*œœœ˜‹Jšœe˜ešœ œ˜Jšœœ%˜?Jšœ œœ*œ˜T—Jšœ˜—š  œœœ œ#œ˜oJšœ÷™÷Jšœ˜Jšœœ+˜3Jšœ˜——šœ™Jšœœ œœ˜/š œœœ%˜HJšœ%œœ`˜’—š œœœ$˜FJšœ*œœ_˜–—š œœœ$˜CJšœ'œœ˜HJšœB˜BJšœ˜—š œœœ8˜WJšœE™EJšœW˜WJšœ˜Jšœ˜Jšœ7œ˜VJšœ˜—š œœœO˜tšœœ˜šœ>˜DJšœœ˜.JšœT˜TJšœ˜—Jšœ˜Jšœ2˜2—Jšœœ$˜5Jšœ˜—Jš¡"œœœœ˜:š œœœU˜€šœP™Pšœœœœ>˜UJšœœ˜.Jšœ+˜+—Jšœ'˜'šœ#˜#Jšœ2˜2—Jšœœ$˜5Jšœ˜———šœ™J˜Jš œœœ!œƒ˜ÃJš( œœœ1œœ œœ1œœœœœùœÂœœ œœçœ œœ%˜øš #œœœ'œ˜sJš œ œœ,œœ˜\Jšœœ˜ šœ¢$˜˜>Jšœbœ˜gJšœ4˜4Jšœ˜—šœ¢#˜9Jšœ8˜8Jšœ|˜|Jš œœ œœ¢€˜›Jšœbœ˜gJšœ˜—Jšœœ˜Jšœ¢/œ˜3—š œœœFœ˜nJšœ˜Jš œœœ"œœ˜Fšœ7˜7JšœÕ™ÕJšœ+™+—Jšœ-˜-JšœG˜GJšœ˜Jšœ˜—š œœœ?˜iJšœ˜Jš œœœ"œœ˜FšœB˜BJšœÞ™ÞJšœ+™+—Jšœ-˜-JšœJ˜JJšœ˜Jšœ˜—Jš œœœ2˜Nšœð™ðJšœ$˜$Jšœ˜J˜ Jšœ ˜ JšœF˜FJšœœœ˜(Jš œœœœ œ˜@šœ$˜*Jšœ%™%—Jšœ œ˜#JšœS˜Sš œœœœ¢5˜NJšœ™—šœ;˜;Jšœ™—Jšœ(œ ˜:Jšœ˜—š œœœ>˜`Jšœ{™{Jšœœ˜.Jšœ œœ˜š œœœ"œœ˜FJšœœ œ˜.—Jšœ˜Jšœœ œœ˜.JšœN˜NJšœœ œœ˜.Jšœ œ˜+Jšœ˜Jš¡œœœœ˜*—š  œœœ-˜HJ™=šœ,œœ˜BJšœM˜M—J˜J˜—š  œœœœ!˜\Jšœ œ˜šœ,œœ˜BJšœI˜I—Jšœ˜J˜—š œœœy˜œJ™ÿJšœK˜KJšœ;˜;JšœC˜CJšœ$˜$Jšœ#˜#Jšœ^˜^Jšœ5˜5Jšœz˜zJ˜—š  œœœ$œ œ˜_Jšœõ™õJšœœ˜;JšœG˜GJšœ5œœœ˜JJšœ>˜>š œœœ%œœ˜IJšœT˜TJšœ/˜/—Jšœ˜Jšœ˜—Jš  œœœ)œœœÓœœ ˜ãJš $œœœ1œœœ)œœœ9œ˜öJš œœœ<œœœ?œœœ$œ˜ï—šœ™Jš œœœœœ œ–œœœœœ œœ!œ¢"œ˜ˆš  œœœ"œ œ˜bJšœ%œ$œ'œ#œœœ˜­J™/š œœœRœœ˜”Jšœ'œœœ˜;—Jšœ˜Jšœ0˜0Jšœ¢$œ˜)—Jš œœœœEœœŽœœœ œœœ œœ œ=˜¶Jš œœœœHœœ‚œœœ œœœ œœ œ@˜³Jš   œœœ-œœH˜¦Jš œœœ‘œ˜Ïš œœœ˜2Jšœ²™²Jšœ6˜6Jšœ˜Jšœ˜Jšœ˜Jšœ œ˜!Jšœ ˜—Jš œœœ;œ œœœœRœ(œœ˜¿Jš  œœœ/œ œ˜ƒšœŠ™ŠJšœœœ˜-šœœ¢˜=J˜ Jšœ"œœ˜5—š œœœ*œœ˜Hšœ œ˜J˜ Jšœ œ˜Jšœ ¢˜/Jšœ ˜ Jšœ˜Jšœ˜—Jšœ*˜.—Jšœ˜Jšœ˜Jšœ˜—Jš  œœœ/œ œ˜ŒJšœÓ™ÓJšœœœ˜-šœœ¢˜=Jšœ"œœ˜5š œœœ*œœ˜Hšœ œ˜Jšœ œ˜Jšœ ¢˜/Jšœ ˜ Jšœ˜Jšœ˜—Jšœ*˜.—Jšœ˜Jšœ œ˜Jšœ˜J˜—š œœœ ˜CJšœ,˜,šœ œ˜Jšœ?˜?Jšœœ˜—Jšœœ˜Jšœ˜—š œœœ(˜OJš œœœ"œœ˜FJšœ*˜*Jšœ˜Jšœ˜——šœ$™$š, œœœ œœœœ!œœœœœœœœ œœœœœœœ˜´Jš¡ œœœœ˜$Jš¡ œœœœ˜%—š  œœœ œœ2˜{Jšœc™cJšœ˜Jšœ œ˜JšœAœ˜FJšœ œœœ˜0Jšœ˜Jš¡œœœœ˜(—Jš œœœ œœœ-œJœœ˜êJšN œœœ œ œ8œœœœœœœœœœœ œœ œœœœœœœœSœ œœœœœœœ œ8œœœœ˜çJš$ œœœ$œœœ-œœœœœœœœœ0œœœ˜ÓJš$ œœœ,œœœœœ)œœœœ+œœœœœœ˜›Jš& œ œ1œœœœ(œ'œœœœœœœœœ8œœœ˜¢Jš& œœœ9œœœœœœ)œœœœ3œœœœœœ˜¶Jš& œœœ œœ'œœIœœœœ*œœœœœœœœ˜ÐJš& œœœ œœ!œœ5œœœœ!œœœ œœœœœ˜ªJš$ œœœ œœœœ5œœœœ!œœœœœœœ˜ûJ˜Jš$ œœœ œœœœ0œœœœ!œœœœœœœ˜úJš& œœœ œœœœ7œœœœ#œœœœœœœœ˜°Jš² œœœ œœœœ3œœœœ!œœœœœœœ œœœ œœœÇœœœœœ3œ5œœœ1œœœœœlœ) œœœœœœœœœœ   œœœ œœ œ œœœœœ`œœœœ œ œœ œ œœ  œœœœœœ œœ$ œœœœœœœœœ œœ˜„Jš8 $œœœœœ2œPœ*œœœœœœœœœœœœœ"œ3œœœœœœœ˜‘Jš$ #œœœœœ}œ!œœœœœœœœ"œ3œœœ˜ñJšœœœ˜$—šœ.™.JšÈ œœ$œ[œœœœœœœœœ œœ œ œœœ œœ*œbœœœœœœ œœ œ œœ œ œ œœ  œœ*œ}œœœœœœœ œœ œ œœœ  œœ(œtœœœœœœœ œœ œ œœœ  œœ,œ€œœœœœœœ œœ œ œœœ œœ7œœœœœœœœ œœ œ œœœ ˜‚—šœ ™ Nšœ™Jš  œœœœœ>˜…Jšœœœ˜-Jšœœ#˜:Jš  œœœœœœœœœF˜²Nšœ™Jš  œœœœ!œ>˜šJšœœœ˜3Jšœœ'  œœœœœœœœœC˜ùNšœ™Jšˆ œ œœ œœO œ œœ œœœœœœœ4œ œœ  #œ œœ œœœœœœœœœ]œ œ œœœ œœœœœ œ œœœœ œœœœ6 œœœœ”œœ6œFœœ-œ)  œœœœœœœœœB˜† Nšœ™Jš  œœœœ$œA˜£Jšœœœ˜9Jšœœ)˜FJš  œœœœœœœœœC˜¸Nšœ™š œœœœ˜RJšœ˜Jšœ˜—š œœœ$œ˜iJ™_Jšœ œœ2˜CJšœ˜Jšœœ˜š œœœ œœ˜DJšœ œ˜#Jšœœ ˜—Jšœ˜Jšœ˜Jšœ˜—Nšœ™JšJ œœœ$œ œœœ œœœœœœœœ œœœ  $œœœ œœœ œœœœ œ œœœœ:œ œœEœq˜®—™™š œœœœ#˜fJ™kJšœ˜Jšœ œ˜šœ,œœ˜BJšœ˜šœœ,˜6Jšœ œ˜&——Jšœ˜J˜—š  œœœœœœ˜^šœ,œœ˜BJš œ%œœœœ˜?—Jšœ˜Jšœœ˜Jšœ˜—š œœœ&œ,˜xJšœ5™5Jšœœ˜šœ-œœ˜Cšœœ,˜6Jšœœ"˜<——Jšœ˜J˜—š œœœœ˜bJšœu™uJšœœ˜ šœ,œœ˜BJšœ/˜/—Jšœ˜J˜———šœ™Jš œœ˜šœ™Jšœœœ˜2Jšœ˜—Jšœ ˜ Jšœ˜——…—‹XÀ©