DIRECTORY CastRays, CoordSys, CSGGraphics, DisplayList3d, DisplayList3dPrivate, Graphics, GraphicsColor, IO, Matrix3d, PriorityQueue, Rope, SV2d, SV3d, SVArtwork, SVError, SVModelTypes, SVRayTypes, SVSceneTypes, SVTransforms; DisplayList3dImplB: PROGRAM IMPORTS CastRays, CoordSys, CSGGraphics, DisplayList3d, DisplayList3dPrivate, Graphics, GraphicsColor, IO, Matrix3d, PriorityQueue, Rope, SVArtwork, SVError, SVTransforms EXPORTS DisplayList3d, DisplayList3dPrivate = BEGIN Camera: TYPE = SVModelTypes.Camera; Classification: TYPE = SVRayTypes.Classification; Color: TYPE = GraphicsColor.Color; CoordSysList: TYPE = SVModelTypes.CoordSysList; CoordSystem: TYPE = SVModelTypes.CoordSystem; CSGTree: TYPE = SVRayTypes.CSGTree; DrawStyle: TYPE = SVModelTypes.DrawStyle; FileCamera: TYPE = REF FileCameraObj; FileCameraObj: TYPE = SVSceneTypes.FileCameraObj; FileCameraList: TYPE = SVSceneTypes.FileCameraList; FrameBox: TYPE = SVSceneTypes.FrameBox; Matrix4by4: TYPE = SV3d.Matrix4by4; Plane: TYPE = SV3d.Plane; Point2d: TYPE = SV2d.Point2d; Point3d: TYPE = SV3d.Point3d; PointSetOp: TYPE = SVRayTypes.PointSetOp; -- {union, intersection, difference} Poly3d: TYPE = SV3d.Poly3d; Primitive: TYPE = SVRayTypes.Primitive; Ray: TYPE = SVRayTypes.Ray; Shape: TYPE = SVSceneTypes.Shape; Vector: TYPE = SV3d.Vector; Database: TYPE = REF DatabaseObj; DatabaseObj: TYPE = SVSceneTypes.DatabaseObj; Scene: TYPE = REF SceneObj; SceneObj: TYPE = SVSceneTypes.SceneObj; Artwork: TYPE = SVModelTypes.Artwork; Assembly: TYPE = REF AssemblyObj; AssemblyObj: TYPE = SVSceneTypes.AssemblyObj; ToolData: TYPE = REF ToolDataObj; ToolDataObj: TYPE = SVSceneTypes.ToolDataObj; AssemblyList: TYPE = REF AssemblyListObj; AssemblyListObj: TYPE = SVSceneTypes.AssemblyListObj; LightSource: TYPE = REF LightSourceObj; LightSourceObj: TYPE = SVModelTypes.LightSourceObj; LightSourceList: TYPE = SVModelTypes.LightSourceList; MasterObjectClass: TYPE = REF MasterObjectClassObj; MasterObjectClassObj: TYPE = SVSceneTypes.MasterObjectClassObj; MasterObjectClassList: TYPE = SVSceneTypes.MasterObjectClassList; FileoutProc: TYPE = SVSceneTypes.FileoutProc; FileinProc: TYPE = SVSceneTypes.FileinProc; MasterObject: TYPE = REF MasterObjectRec; MasterObjectRec: TYPE = SVSceneTypes.MasterObjectRec; MasterObjectList: TYPE = SVSceneTypes.MasterObjectList; FileoutPolyProc: TYPE = SVSceneTypes.FileoutPolyProc; RayCastProc: TYPE = SVRayTypes.RayCastProc; RayCastNoBBoxesProc: TYPE = SVRayTypes.RayCastNoBBoxesProc; RayCastBoundingSpheresProc: TYPE = SVRayTypes.RayCastBoundingSpheresProc; BoundHedronProc: TYPE = SVSceneTypes.BoundHedronProc; PreprocessProc: TYPE = SVSceneTypes.PreprocessProc; LineDrawProc: TYPE = SVSceneTypes.LineDrawProc; NormalsDrawProc: TYPE = SVSceneTypes.NormalsDrawProc; CountPlanarSurfacesProc: TYPE = SVSceneTypes.CountPlanarSurfacesProc; GetPlanarSurfacesProc: TYPE = SVSceneTypes.GetPlanarSurfacesProc; PlanarSurface: TYPE = REF PlanarSurfaceObj; PlanarSurfaceObj: TYPE = SVSceneTypes.PlanarSurfaceObj; PlanarSurfaceList: TYPE = SVSceneTypes.PlanarSurfaceList; DrawPlanarSurfaceProc: TYPE = SVSceneTypes.DrawPlanarSurfaceProc; DrawSubBoxesProc: TYPE = SVSceneTypes.DrawSubBoxesProc; DrawSubSpheresProc: TYPE = SVSceneTypes.DrawSubSpheresProc; NoOpFilein: PUBLIC FileinProc = {}; NoOpFileout: PUBLIC FileoutProc = {}; NoOpFileoutPoly: PUBLIC FileoutPolyProc = {}; NoOpRayCast: PUBLIC RayCastProc = { class _ CastRays.GetClassFromPool[]; CastRays.MakeClassAMiss[class]; }; NoOpRayCastNoBBoxes: PUBLIC RayCastNoBBoxesProc = { class _ CastRays.GetClassFromPool[]; CastRays.MakeClassAMiss[class]; }; NoOpRayCastBoundingSpheres: PUBLIC RayCastBoundingSpheresProc = { class _ CastRays.GetClassFromPool[]; CastRays.MakeClassAMiss[class]; }; NoOpBoundHedron: PUBLIC BoundHedronProc = {RETURN[NIL]}; NoOpPreprocess: PUBLIC PreprocessProc = {}; -- don't preprocess anything NoOpLineDraw: PUBLIC LineDrawProc = {}; -- don't draw anything NoOpNormalsDraw: PUBLIC NormalsDrawProc = {}; -- don't draw anything NoOpCountPlanarSurfaces: PUBLIC CountPlanarSurfacesProc = {RETURN[0]}; NoOpGetPlanarSurfaces: PUBLIC GetPlanarSurfacesProc = {RETURN[NIL]}; NoOpDrawPlanarSurface: PUBLIC DrawPlanarSurfaceProc = {}; -- don't draw anything NoOpDrawSubBoxes: PUBLIC DrawSubBoxesProc = {}; -- don't draw anything NoOpDrawSubSpheres: PUBLIC DrawSubSpheresProc = {}; -- don't draw anything DeleteMasterObjectNamed: PUBLIC PROC [moName: Rope.ROPE, scene: Scene] RETURNS [found: BOOL] = { mo, beforeMo, afterMo: MasterObjectList; [beforeMo, mo, afterMo, found] _ DisplayList3dPrivate.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] = { shape: Shape; 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"] OR Rope.Equal[mo.class.name, "halfSpace"] THEN RETURN[TRUE]; FOR primitiveAssemblies: LIST OF Assembly _ DisplayList3d.ListOfPrimAssemblies[scene.assembly, scene], primitiveAssemblies.rest UNTIL primitiveAssemblies = NIL DO shape _ NARROW[primitiveAssemblies.first.shape]; IF shape.mo = mo THEN RETURN[TRUE]; ENDLOOP; found _ DeleteMasterObjectNamed[mo.name, scene]; }; -- end of DeleteMasterObjectIfUnused DeleteCoordSysAndChildren: PUBLIC PROC [cs: CoordSystem, scene: Scene] = { CoordSys.DeleteCoordSysAndChildren[cs, scene.coordSysRoot]; }; -- end of DeleteCoordSysNamed DeleteLightSourceNamed: PUBLIC PROC [lsName: Rope.ROPE, scene: Scene] = { ls, beforeLS, afterLS: LightSourceList; notFound: BOOL _ FALSE; [beforeLS, ls, afterLS] _ DisplayList3dPrivate.FindLightSourceAndNeighborsFromName[lsName, scene.lightSources !DisplayList3dPrivate.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.shape _ NEW[AssemblyListObj _ [NIL, union] ]; ClearCoordSystems[scene]; ClearMasterObjects[scene]; }; ClearCoordSystems: PUBLIC PROC [scene: Scene] = { world: CoordSystem _ scene.coordSysRoot; DeleteCoordSysAndChildren[world.children.first, scene]; -- assumes this is sceneAssembly. }; 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.shape, AssemblyList] THEN [assembly.shape, success] _ RemoveFromAssemblyList[subassembly, NARROW[assembly.shape, AssemblyList], scene] ELSE ERROR; }; RemoveFromAssemblyList: PRIVATE PROC [a: Assembly, al: AssemblyList, scene: Scene] RETURNS [newAl: AssemblyList, success: BOOL] = { lastAssemblyList: LIST OF Assembly _ al.list; DeleteAllAssembliesSittingOn[a, scene]; 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: PUBLIC 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] = { DeleteCoordSysAndChildren[a.coordSys, scene]; }; DeleteAllPrimitivesOfClass: PUBLIC PROC [className: Rope.ROPE, scene: Scene] = { moClass: MasterObjectClass; success: BOOL; [moClass, success] _ DisplayList3d.FindClassFromName[className]; IF NOT success THEN { SVError.Append[Rope.Cat["DeleteAllPrimitivesOfClass: Couldn't find class ", className, "."], TRUE, TRUE]; SVError.Blink[]; }; DeleteAllOfClassAux[moClass, scene.assembly, scene]; }; DeleteAllOfClassAux: PRIVATE PROC [moClass: MasterObjectClass, root: Assembly, scene: Scene] = { WITH root.shape SELECT FROM shape: Shape => { child, parent: Assembly; success: BOOL; IF shape.mo.class = moClass THEN { [child, parent] _ DisplayList3d.FindAssemblyFromName[root.name, scene]; IF child # root THEN ERROR; success _ DisplayList3d.DeleteSubassemblyFromAssembly[child, parent, scene]; IF NOT success THEN ERROR; }; }; alist: AssemblyList => { FOR list: LIST OF Assembly _ alist.list, list.rest UNTIL list = NIL DO DeleteAllOfClassAux[moClass, list.first, scene]; ENDLOOP; }; ENDCASE => ERROR; }; DeleteAllAssembliesSittingOn: PUBLIC PROC [chair: Assembly, scene: Scene] = { DeleteAllSittingOnAux[chair.name, scene.assembly, scene]; }; DeleteAllSittingOnAux: PRIVATE PROC [chairName: Rope.ROPE, root: Assembly, scene: Scene] = { child, parent: Assembly; success: BOOL; IF Rope.Equal[root.sittingOn, chairName, TRUE] THEN { [child, parent] _ DisplayList3d.FindAssemblyFromName[root.name, scene]; IF child # root THEN ERROR; success _ DisplayList3d.DeleteSubassemblyFromAssembly[child, parent, scene]; IF NOT success THEN ERROR; RETURN; }; WITH root.shape SELECT FROM shape: Shape => {}; alist: AssemblyList => { FOR list: LIST OF Assembly _ alist.list, list.rest UNTIL list = NIL DO DeleteAllSittingOnAux[chairName, list.first, scene]; ENDLOOP; }; ENDCASE => ERROR; }; CopyAssemblyAndSonsRename: PUBLIC PROC [assembly: Assembly, scene: Scene, prefix: Rope.ROPE, parent: Assembly] RETURNS [copy: Assembly] = { moFound: BOOL; IF NewNamesAlreadyPresent[assembly, scene, prefix] THEN SIGNAL DisplayList3d.NameAlreadyPresent; WITH assembly.shape SELECT FROM alist: AssemblyList => {-- assembly is a composite assembly. copyCS: CoordSystem _ CoordSys.CreateCoordSysInTree[name: Rope.Concat[prefix, assembly.name], mat: assembly.coordSys.mat, parent: parent.coordSys, root: scene.coordSysRoot]; copy _ DisplayList3d.CreateClusterAssemblyAtExistingCoordSys[Rope.Concat[prefix, assembly.name], alist.pointSetOp, scene, copyCS]; FOR list: LIST OF Assembly _ alist.list, list.rest UNTIL list = NIL DO [] _ CopyAssemblyAndSonsRename[list.first, scene, prefix, copy]; ENDLOOP; }; shape: Shape => { -- assembly is a primitive assembly artworkCopy: Artwork _ SVArtwork.Copy[assembly.artwork]; copyCS: CoordSystem _ CoordSys.CreateCoordSysInTree[name: Rope.Concat[prefix, assembly.name], mat: assembly.coordSys.mat, parent: parent.coordSys, root: scene.coordSysRoot]; [copy, moFound] _ DisplayList3d.CreatePrimitiveAtExistingCoordSys[Rope.Concat[prefix, assembly.name], shape.mo.name, CoordSys.GetScalars[shape.coordSys], scene, copyCS, 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). }; ENDCASE => ERROR; DisplayList3d.ConnectAssemblyToParent[copy, parent]; }; -- end of CopyAssemblyAndSons CopyAssemblyAndSonsNoRename: PUBLIC PROC [assembly: Assembly, newScene: Scene, parent: Assembly] RETURNS [copy: Assembly] = { moFound: BOOL; IF DisplayList3d.AnyNamesAlreadyPresent[assembly, newScene] THEN SIGNAL DisplayList3d.NameAlreadyPresent; WITH assembly.shape SELECT FROM alist: AssemblyList => {-- assembly is a composite assembly. copyCS: CoordSystem _ CoordSys.CreateCoordSysInTree[name: assembly.name, mat: assembly.coordSys.mat, parent: parent.coordSys, root: newScene.coordSysRoot]; copy _ DisplayList3d.CreateClusterAssemblyAtExistingCoordSys[assembly.name, alist.pointSetOp, newScene, copyCS]; FOR list: LIST OF Assembly _ alist.list, list.rest UNTIL list = NIL DO [] _ CopyAssemblyAndSonsNoRename[list.first, newScene, copy]; ENDLOOP; }; shape: Shape => { -- assembly is a primitive assembly artworkCopy: Artwork _ SVArtwork.Copy[assembly.artwork]; copyCS: CoordSystem _ CoordSys.CreateCoordSysInTree[name: assembly.name, mat: assembly.coordSys.mat, parent: parent.coordSys, root: newScene.coordSysRoot]; [copy, moFound] _ DisplayList3d.CreatePrimitiveAtExistingCoordSys[assembly.name, shape.mo.name, CoordSys.GetScalars[shape.coordSys], newScene, copyCS, 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). }; ENDCASE => ERROR; DisplayList3d.ConnectAssemblyToParent[assembly, parent]; }; -- end of CopyAssemblyAndSonsNoRename ReadAlpha: PRIVATE PROC [s: IO.STREAM] RETURNS [base: Rope.ROPE] = { skip: INT; [base, skip] _ IO.GetTokenRope[s, AlphaBreakProc]; }; AlphaBreakProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = TRUSTED { RETURN[IF char = '. THEN break ELSE other] }; FindUniqueAssemblyNum: PRIVATE PROC [scene: Scene] RETURNS [num: NAT] = { num _ FindUniqueAssemblyNumAux[scene.assembly]; num _ num + 1; }; FindUniqueAssemblyNumAux: PRIVATE PROC [assembly: Assembly] RETURNS [num: NAT] = { thisNum: NAT; WITH assembly.shape SELECT FROM alist: AssemblyList => {-- assembly is a composite assembly. [----, num] _ CoordSys.BaseAndNumber[assembly.name]; FOR l: LIST OF Assembly _ alist.list, l.rest UNTIL l = NIL DO thisNum _ FindUniqueAssemblyNumAux[l.first]; num _ MAX[num, thisNum]; ENDLOOP; }; shape: Shape => { -- assembly is a primitive assembly [----, num] _ CoordSys.BaseAndNumber[assembly.name]; }; ENDCASE => ERROR; }; CopyAssemblyAndSonsUniqueNames: PUBLIC PROC [assembly: Assembly, oldScene: Scene, newScene: Scene, parent: Assembly] RETURNS [copy: Assembly] = { num: NAT; success: BOOL; num _ FindUniqueAssemblyNum[newScene]; IF oldScene = newScene THEN copy _ CopyAssemblyAndSonsUniqueNamesAux[assembly, newScene, parent, num] ELSE { success _ CopyNeededMasterObjects[assembly, oldScene, newScene]; IF NOT success THEN { SVError.Append[Rope.Cat["Masterobject name conflict scenes: ", oldScene.name, "/", newScene.name], TRUE, TRUE]; SVError.Blink[]; RETURN; }; copy _ CopyAssemblyAndSonsUniqueNamesAux[assembly, newScene, parent, num]; }; }; CopyAssemblyAndSonsUniqueNamesAux: PUBLIC PROC [assembly: Assembly, newScene: Scene, parent: Assembly, num: NAT] RETURNS [copy: Assembly] = { thisBase, unique: Rope.ROPE; thisNum: NAT; moFound: BOOL; WITH assembly.shape SELECT FROM alist: AssemblyList => {-- assembly is a composite assembly. copyCS: CoordSystem; [thisBase, thisNum] _ CoordSys.BaseAndNumber[assembly.name]; unique _ IO.PutFR["%g.%g",[rope[thisBase]], [integer[num+thisNum]]]; copyCS _ CoordSys.CreateCoordSysInTree[name: unique, mat: assembly.coordSys.mat, parent: parent.coordSys, root: newScene.coordSysRoot]; copy _ DisplayList3d.CreateClusterAssemblyAtExistingCoordSys[unique, alist.pointSetOp, newScene, copyCS]; FOR list: LIST OF Assembly _ alist.list, list.rest UNTIL list = NIL DO [] _ CopyAssemblyAndSonsUniqueNamesAux[list.first, newScene, copy, num]; ENDLOOP; }; shape: Shape => { -- assembly is a primitive assembly artworkCopy: Artwork _ SVArtwork.Copy[assembly.artwork]; copyCS: CoordSystem; [thisBase, thisNum] _ CoordSys.BaseAndNumber[assembly.name]; unique _ IO.PutFR["%g.%g",[rope[thisBase]], [integer[num+thisNum]]]; copyCS _ CoordSys.CreateCoordSysInTree[name: unique, mat: assembly.coordSys.mat, parent: parent.coordSys, root: newScene.coordSysRoot]; [copy, moFound] _ DisplayList3d.CreatePrimitiveAtExistingCoordSys[unique, shape.mo.name, CoordSys.GetScalars[shape.coordSys], newScene, copyCS, 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). }; ENDCASE => ERROR; DisplayList3d.ConnectAssemblyToParent[copy, parent]; }; AddMOsToScene: PRIVATE PROC [moList: MasterObjectList, scene: Scene] = { FOR list: MasterObjectList _ moList, list.rest UNTIL list = NIL DO scene.masterObjects _ DisplayList3dPrivate.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 _ DisplayList3dPrivate.AppendToMasterObjects[DisplayList3d.CopyMasterObject[list.first], copyList]; ENDLOOP; }; CopyNeededMasterObjects: PUBLIC PROC [assembly: Assembly, fromScene, toScene: Scene] RETURNS [success: BOOL] = { moList: MasterObjectList; toMoList: MasterObjectList; neededList: MasterObjectList; success _ TRUE; moList _ DisplayList3d.MasterObjectsOfAssembly[assembly, fromScene]; toMoList _ DisplayList3d.MasterObjectsOfScene[toScene]; neededList _ DisplayList3dPrivate.MoListMinusMoList[moList, toMoList]; neededList _ CopyMOList[neededList]; AddMOsToScene[neededList, toScene]; }; RemoveDuplicateMOs: PUBLIC 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: PUBLIC 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: PUBLIC PROC [moList: MasterObjectList] RETURNS [copy: MasterObjectList] = { copy _ NIL; FOR list: MasterObjectList _ moList, list.rest UNTIL list = NIL DO copy _ DisplayList3dPrivate.AppendToMasterObjects[list.first, copy]; ENDLOOP; }; NewNamesAlreadyPresent: PUBLIC PROC [assembly: Assembly, scene: Scene, prefix: Rope.ROPE] RETURNS [BOOL] = { newName: Rope.ROPE _ Rope.Concat[prefix, assembly.name]; IF DisplayList3d.AssemblyNameIsPresent[newName, scene] THEN RETURN [TRUE]; WITH assembly.shape SELECT FROM shape: Shape => 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]; }; DrawScene: PUBLIC PROC [dc: Graphics.Context, scene: Scene, camera: Camera] = { mark: Graphics.Mark; mark _ Graphics.Save[dc]; SELECT camera.style FROM wire => DrawWireAssemblies[dc, scene, camera]; shaded => DrawShadedAssemblies[dc, scene, camera]; normals => DrawNormalsAssemblies[dc, scene, camera]; ENDCASE => SIGNAL NotYetImplemented; IF NOT camera.frame.fullScreen THEN { SetColor[dc, camera, GraphicsColor.black]; CSGGraphics.DrawFrame[dc, camera]; }; Graphics.Restore[dc, mark]; }; NotYetImplemented: PUBLIC SIGNAL = CODE; DrawWireAssemblies: PRIVATE PROC [dc: Graphics.Context, scene: Scene, camera: Camera] = { assemblyName: Rope.ROPE; found: BOOL; assembly: Assembly; FOR list: LIST OF Rope.ROPE _ camera.visibleAssemblies, list.rest UNTIL list = NIL DO assemblyName _ list.first; found _ TRUE; [assembly, ----] _ DisplayList3d.FindAssemblyFromName[assemblyName, scene !DisplayList3d.AssemblyNotFound => {found _ FALSE; CONTINUE}]; IF found THEN { SVTransforms.TellAboutCameraAndWorld[assembly.coordSys, camera, scene]; DrawWireAssembly[dc, assembly, scene, camera]; }; ENDLOOP; }; DrawShadedAssemblies: PRIVATE PROC [dc: Graphics.Context, scene: Scene, camera: Camera] = { assemblyName: Rope.ROPE; assembly: Assembly; found: BOOL; box: Graphics.Box; box _ Graphics.GetBounds[dc]; SetColor[dc, camera, scene.backgroundColor]; Graphics.DrawBox[dc, box]; FOR list: LIST OF Rope.ROPE _ camera.visibleAssemblies, list.rest UNTIL list = NIL DO assemblyName _ list.first; found _ TRUE; [assembly, ----] _ DisplayList3d.FindAssemblyFromName[assemblyName, scene !DisplayList3d.AssemblyNotFound => {found _ FALSE; CONTINUE}]; IF found THEN { SVTransforms.TellAboutCameraAndWorld[assembly.coordSys, camera, scene]; DrawShadedAssembly[dc, assembly, scene, camera]; }; ENDLOOP; }; DrawNormalsAssemblies: PRIVATE PROC [dc: Graphics.Context, scene: Scene, camera: Camera] = { assemblyName: Rope.ROPE; assembly: Assembly; found: BOOL; FOR list: LIST OF Rope.ROPE _ camera.visibleAssemblies, list.rest UNTIL list = NIL DO assemblyName _ list.first; found _ TRUE; [assembly, ----] _ DisplayList3d.FindAssemblyFromName[assemblyName, scene !DisplayList3d.AssemblyNotFound => {found _ FALSE; CONTINUE}]; IF found THEN { SVTransforms.TellAboutCameraAndWorld[assembly.coordSys, camera, scene]; DrawNormalsAssembly[dc, assembly, scene, camera]; }; ENDLOOP; }; DrawAssembly: PUBLIC PROC [dc: Graphics.Context, assembly: Assembly, scene: Scene, camera: Camera] = { SVTransforms.TellAboutCameraAndWorld[assembly.coordSys, camera, scene]; SELECT camera.style FROM wire => DrawWireAssembly[dc, assembly, scene, camera]; shaded => DrawShadedAssembly[dc, assembly, scene, camera]; normals => DrawNormalsAssembly[dc, assembly, scene, camera]; ENDCASE => SIGNAL NotYetImplemented; }; SetColor: PRIVATE PROC [dc: Graphics.Context, camera: Camera, color: Color] = { IF camera.colorFilm THEN Graphics.SetColor[dc, color] ELSE { intensity: REAL _ GraphicsColor.ColorToIntensity[color]; Graphics.SetColor[dc, GraphicsColor.IntensityToColor[intensity]]}; }; DrawWireAssembly: PRIVATE PROC [dc: Graphics.Context, assembly: Assembly, scene: Scene, camera: Camera] = { Graphics.SetColor[dc, GraphicsColor.black]; DrawWireAssembly2[dc, assembly, camera]; }; DrawWireAssembly2: PRIVATE PROC [dc: Graphics.Context, assembly: Assembly, camera: Camera] = { SELECT assembly.showAs FROM tool => { toolMasterObject: MasterObject _ assembly.toolMasterObject; IF toolMasterObject = NIL THEN { SVError.Append[Rope.Cat["Assembly ", assembly.name, " is a tool but has no tool data. Contact implementor."], TRUE, TRUE]; RETURN; }; toolMasterObject.class.lineDraw[dc, toolMasterObject.lineBody, camera, assembly.coordSys]; RETURN; }; normal => { WITH assembly.shape SELECT FROM assems: AssemblyList => { FOR subassemblies: LIST OF Assembly _ assems.list, subassemblies.rest UNTIL subassemblies = NIL DO DrawWireAssembly2[dc: dc, assembly: subassemblies.first, camera: camera]; ENDLOOP; }; shape: Shape => { shape.mo.class.lineDraw[dc, shape.mo.lineBody, camera, shape.coordSys]; }; ENDCASE => ERROR; }; invisible => {}; both => ERROR SVError.NotYetImplemented; ENDCASE => ERROR; }; DrawShadedAssembly: PRIVATE PROC [dc: Graphics.Context, assembly: Assembly, scene: Scene, camera: Camera] = { predictedQueueSize: NAT _ CountSurfacesInAssembly[assembly]; surfaceQueue: PriorityQueue.Ref _ PriorityQueue.Predict[predictedQueueSize, DeeperPlanarSurface]; mo: MasterObject; thisPlanarSurf: PlanarSurface; mark: Graphics.Mark _ Graphics.Save[dc]; PutAssemblyOnQueue[assembly, surfaceQueue, camera.coordSys]; FOR i: INT IN[1..PriorityQueue.Size[surfaceQueue]] DO thisPlanarSurf _ NARROW[PriorityQueue.Remove[surfaceQueue]]; mo _ thisPlanarSurf.mo; mo.class.drawSurf[dc, thisPlanarSurf, scene.lightSources, camera]; ENDLOOP; Graphics.Restore[dc, mark]; }; CountSurfacesInAssembly: PRIVATE PROC [assembly: Assembly] RETURNS [surfCount: NAT] = { WITH assembly.shape SELECT FROM assems: AssemblyList => surfCount _ CountSurfacesInAssemblyList[assems]; shape: Shape => surfCount _ shape.mo.class.countSurf[shape.mo]; ENDCASE => ERROR; }; CountSurfacesInAssemblyList: PRIVATE PROC [asl: AssemblyList] RETURNS [surfCount: NAT] = { surfCount _ 0; FOR list: LIST OF Assembly _ asl.list, list.rest UNTIL list = NIL DO surfCount _ surfCount + CountSurfacesInAssembly[list.first]; ENDLOOP; }; PutAssemblyOnQueue: PRIVATE PROC [assembly: Assembly, q: PriorityQueue.Ref, cameraCS: CoordSystem] = { thisSurf: PlanarSurface; cameraNormal: Vector; surfList: PlanarSurfaceList; SELECT assembly.showAs FROM tool => { toolMasterObject: MasterObject _ assembly.toolMasterObject; surfList _ toolMasterObject.class.getSurf[assembly, cameraCS]; FOR surfList _ surfList, surfList.rest UNTIL surfList = NIL DO thisSurf _ surfList.first; cameraNormal _ Matrix3d.UpdateVectorWithInverse[assembly.coordSys.cameraWRTlocal, thisSurf.normal]; thisSurf.normal _ cameraNormal; PriorityQueue.Insert[q, thisSurf]; ENDLOOP; }; normal => { WITH assembly.shape SELECT FROM assems: AssemblyList => PutAssemblyListOnQueue[assems, q, cameraCS]; shape: Shape => { surfList _ shape.mo.class.getSurf[assembly, cameraCS]; FOR surfList _ surfList, surfList.rest UNTIL surfList = NIL DO thisSurf _ surfList.first; cameraNormal _ Matrix3d.UpdateVectorWithInverse[shape.coordSys.cameraWRTlocal, thisSurf.normal]; thisSurf.normal _ cameraNormal; IF thisSurf.normal[3] >0 THEN PriorityQueue.Insert[q,thisSurf]; ENDLOOP; }; ENDCASE => ERROR; }; invisible => {}; both => ERROR SVError.NotYetImplemented; ENDCASE => ERROR; }; -- end of PutAssemblyOnQueue PutAssemblyListOnQueue: PRIVATE PROC [asl: AssemblyList, q: PriorityQueue.Ref, cameraCS: CoordSystem] = { FOR list: LIST OF Assembly _ asl.list, list.rest UNTIL list = NIL DO PutAssemblyOnQueue[list.first, q, cameraCS]; ENDLOOP; }; DeeperPlanarSurface: SAFE PROC [x,y: PriorityQueue.Item, data: REF _ NIL] RETURNS [BOOL] = TRUSTED { xS: PlanarSurface _ NARROW[x]; yS: PlanarSurface _ NARROW[y]; RETURN[xS.depth < yS.depth]; }; DrawNormalsAssembly: PROC [dc: Graphics.Context, assembly: Assembly, scene: Scene, camera: Camera] = { Graphics.SetColor[dc, GraphicsColor.black]; DrawNormalsAssembly2[dc, assembly, scene, camera]; }; DrawNormalsAssembly2: PROC [dc: Graphics.Context, assembly: Assembly, scene: Scene, camera: Camera] = { lightSources: LightSourceList _ scene.lightSources; WITH assembly.shape SELECT FROM assems: AssemblyList => { FOR subassemblies: LIST OF Assembly _ assems.list, subassemblies.rest UNTIL subassemblies = NIL DO DrawNormalsAssembly2[dc: dc, assembly: subassemblies.first, scene: scene, camera: camera]; ENDLOOP; }; shape: Shape => { shape.mo.class.normalsDraw[dc, shape.mo.shadeBody, camera, shape.coordSys]; }; ENDCASE => ERROR; }; END. €DisplayList3dImplB.mesa Last edited by Bier on January 10, 1985 5:53:57 pm PST Copyright c 1984 by Xerox Corporation. All rights reserved. Imported Types DisplayList Types Databases, Scenes, Assemblies, and Lightsources Master Object Class Types Master Object Types Noop Procedures A master object can use these entries if it doesn't implement one of these procedures Say you don't have any Return the empty list Delete Parts of the Scene Tree For now, we won't delete the built-in instances. Removes all but WORLD, SCREEN and sceneAssembly. Assumes for now that WORLD, and SCREEN are the first 2 coordsystems on the list. 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. Does 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. className must be a master object class, e.g. "sphere" or "jack". All primitive (leaf) assemblies refering to shapes of this class will be deleted in subtree rooted at root. Removes assembly from the assemblyList of superAssembly and deletes the coordinate systems of all of its children. All assemblies A such that A.sittingOn = chair.name will be deleted along with their children. Removes assembly from the assemblyList of superAssembly and deletes the coordinate systems of all of its children. Copy Parts of the Scene Tree For copying assemblies within the same scene. The copies can refer to the same master object records as other objects in this scene. The prefix rope is prepended to the names of each node as it is copied to distinguish it from the original. CreateClusterAssemblyAtExistingCoordSys is used for filing in, so it doesn't do all we would like. We must wire up parents to the children manually. CopyAssemblyAndSonsRename returns an assembly which is complete and wired up to parent. For copying an assembly from one scene to another. This presents problems since the needed masterobject may not be already present in the target scene. We assume that procedure MergeAssemblyIntoScene has already added the necessary master objects. No prefix is added. We just pray that there are no name conflicts. CreateClusterAssemblyAtExistingCoordSys is used for filing in, so it doesn't do all we would like. We must wire up parents to the children manually. CopyAssemblyAndSonsNoRename returns an assembly which is complete and wired up to parent. Finds an integer such that "." is unique in the scene of assembly for all strings . i.e. Find the highest .num extension in the tree rooted at assembly. oldScene is the scene assembly belongs to. newScene is the scene copy will belong to. parent must be an assembly in the new scene. An attempt to do it right. For assembly and all of its successors, we find an integer a just high enough so that if name.# becomes name.a then all names will be unique. We copy the assembly and its successors and rename them this way. CopyAssemblyAndSonsUniqueNamesAux returns an assembly which is complete and wired up to parent. 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. Assumes that if two master objects have the same name, they are the same. 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. Find Scene Entities from their Names Draw Parts of the Scene Tree CSGGraphics.Clip[dc, camera]; Draw the current bounding frame if there is one. Draw a background color. CSGGraphics.Clip[dc, camera]; -- clip picture to frame Graphics.SetColor[dc, assembly.color]; Get a list of surfaces from each subassembly of "assembly" and draw them with the Painter's Algorithm (back to front) Count the total number of surfaces and make a priority queue of the appropriate size. Now put the surfaces on the queue Take the surfaces off the queue in order and draw them Eliminate most back-facing surfaces at this point by a simple test. Graphics.SetColor[dc, assembly.color]; สH˜Ihead1šœ™Iproc– "Cedar" stylešœ6™6Jšœ ฯmœ1™˜NJšœžœ˜Jšœ žœ˜'Jšœžœ˜Jšœžœ˜!Jšœžœ˜—šœ™Ihead2šœ/™/Jšœ žœžœ ˜!Jšœ žœ˜.Jšœžœžœ ˜Jšœ žœ˜(Jšœ žœ˜%Jšœ žœžœ ˜!Jšœ žœ˜-Jšœ žœ˜!Jšœ-˜-Jšœžœžœ˜)Jšœžœ!˜6Jšœ žœžœ˜'Jšœžœ˜3Jšœžœ ˜5Mšœ™Jšœžœžœ˜3Jšœžœ%˜?Jšœžœ'˜BJšœ žœ˜-Jšœ žœ˜+Mšœ™Jšœžœžœ˜)Jšœžœ ˜5Jšœžœ"˜8Jšœžœ ˜5Jšœ žœ˜+Jšœžœ"˜;Jšœžœ)˜IJšœžœ ˜5Jšœžœ˜3Jšœžœ˜/Jšœžœ ˜5Jšœžœ(˜Ešœžœ&˜AJšœžœžœ˜+Jšœžœ!˜7Jšœžœ"˜9—Jšœžœ&˜AJšœžœ!˜7Jšœžœ#˜;šœ™J– "Cedar" stylešœU™U—J˜Jšฯb œžœ˜#JšŸ œžœ˜%JšŸœžœ˜-šฯn œžœ˜#Jšœ$˜$Jšœ˜Jšœ˜—š œžœ˜3Jšœ$˜$Jšœ˜Jšœ˜—š œžœ˜AJšœ$˜$Jšœ˜Jšœ˜—JšŸœžœžœžœ˜8Jš œžœ2˜HJš  œžœ*˜>Jš œžœ-˜Dš œžœžœ˜FJšœ™—š œžœžœžœ˜DJ™—Jš œžœ3˜PJš œžœ/˜GJš œžœฯc˜K—šœ™š  œžœžœžœžœ žœ˜`Jšœ(˜(Jšœx˜xJšžœžœžœžœ˜Jšžœ žœžœ˜4Jšžœ˜Jšœ$˜$—J˜š  œžœžœ"žœ žœ˜b˜ J™0—Jšžœ%žœ$žœ'žœ#žœ(žœžœžœ˜ืJ˜šžœžœžœ ˜+JšœS˜S—šžœžœž˜"Jšœžœ"˜0Jšžœžœžœžœ˜#—Jšžœ˜Jšœ0˜0Jšœก$˜'J˜—š œžœžœ$˜JJšœ;˜;Jšœก˜ —J˜š œžœžœžœ˜IJšœ'˜'Jšœ žœžœ˜šœm˜mJšœ9žœžœ˜J—Jšžœ žœžœ˜Jšžœ žœžœ˜3Jšžœ˜Jšœ#˜#—J˜š  œžœžœ˜*Jšœžœžœ ˜—šžœžœ˜JšœG˜GLšœ.˜.L˜——Jšžœ˜J˜—š œžœžœ9˜[Jšœžœ˜Jšœ˜Jšœžœ˜ Jšœ˜Jšœ™Jšœ˜Jšœ,˜,Jšœ˜š žœžœžœžœ'žœžœž˜UJšœ˜Jšœžœ˜ šœI˜ILšœ,žœžœ˜>—šžœžœ˜JšœG˜GLšœ0˜0L˜——Jšžœ˜J˜—š œžœžœ9˜\Jšœžœ˜Jšœ˜Jšœžœ˜ š žœžœžœžœ'žœžœž˜UJšœ˜Jšœžœ˜ šœI˜ILšœ,žœžœ˜>—šžœžœ˜JšœG˜GLšœ1˜1L˜——Jšžœ˜J˜J˜—š  œžœžœM˜fJšœG˜GJšœ6™6J˜Jšžœž˜Jšœ6˜6Jšœ:˜:Jšœ<˜šžœ$žœ žœž˜>Jšœ˜Jšœc˜cJšœ˜JšŸœ˜"—Jšžœ˜J˜—šŸœ˜ Jšžœžœž˜JšŸœ>˜DšŸœ ˜Jšœ Ÿœ˜6šžœ$žœ žœž˜>Jšœ˜Jšœ`˜`Jšœ˜JšœC™CJšžœžœŸœ ˜?—Jšžœ˜Jšœ˜—Jšขœžœ˜J˜—JšŸ œ˜JšŸœžœ˜(Jšขœžœ˜Jšœก˜J˜—š œžœžœE˜iš žœžœžœ žœžœž˜DJšœ,˜,—Jšžœ˜Jšœ˜J˜—š œžœžœ!žœžœžœžœžœ˜dJšœžœ˜Jšœžœ˜Jšžœ˜Jšœ˜—J˜š œžœM˜fJšœ+˜+Jšœ2˜2Jšœ˜—J˜š œžœM˜gJšœ3˜3Jšžœžœž˜šœ˜Jšžœžœžœ+˜EJšžœžœž˜JšœZ˜ZJšžœ˜Jšœ˜—šœ˜Jšœ&™&JšœK˜KJšœ˜—Jšžœžœ˜Jšœ˜—Jšœ˜—Jšžœ˜—…—i\›$