<> <> <> <<>> DIRECTORY CastRays, CoordSys, CSGGraphics, DisplayList3d, DisplayList3dPrivate, Imager, ImagerBackdoor, ImagerColor, ImagerColorPrivate, IO, Matrix3d, PriorityQueue, Rope, SV2d, SV3d, SVArtwork, SVError, SVModelTypes, SVRayTypes, SVSceneTypes, SVTransforms; DisplayList3dImplB: PROGRAM IMPORTS CastRays, CoordSys, CSGGraphics, DisplayList3d, DisplayList3dPrivate, Imager, ImagerBackdoor, ImagerColor, ImagerColorPrivate, IO, Matrix3d, PriorityQueue, Rope, SVArtwork, SVError, SVTransforms EXPORTS DisplayList3d, DisplayList3dPrivate = BEGIN <> Camera: TYPE = SVModelTypes.Camera; Classification: TYPE = SVRayTypes.Classification; Color: TYPE = Imager.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] = { << Removes all but WORLD, SCREEN and sceneAssembly.>> << Assumes for now that WORLD, and SCREEN are the first 2 coordsystems on the list.>> 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] = { <." is unique in the scene of assembly for all strings . i.e. Find the highest .num extension in the tree rooted at assembly.>> 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] = { <<**** Naive algorithm for now. Go through moList. Add anything to uniqueList which it doesn't already have>> 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: Imager.Context, scene: Scene, camera: Camera] = { DrawSceneAux: SAFE PROC = TRUSTED { <> 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, Imager.black]; CSGGraphics.DrawFrame[dc, camera]; }; }; Imager.DoSaveAll[dc, DrawSceneAux]; }; NotYetImplemented: PUBLIC SIGNAL = CODE; DrawWireAssemblies: PRIVATE PROC [dc: Imager.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: Imager.Context, scene: Scene, camera: Camera] = { assemblyName: Rope.ROPE; assembly: Assembly; found: BOOL; box: Imager.Rectangle; <> box _ ImagerBackdoor.GetBounds[dc]; SetColor[dc, camera, scene.backgroundColor]; Imager.MaskRectangle[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: Imager.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: Imager.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: Imager.Context, camera: Camera, color: Color] = { currentColor: Imager.Color _ ImagerBackdoor.GetColor[dc]; IF currentColor = ImagerBackdoor.invert THEN RETURN; IF camera.colorFilm THEN Imager.SetColor[dc, color] ELSE { intensity: REAL _ ImagerColorPrivate.ComponentFromColor[NARROW[color], $Intensity]; Imager.SetColor[dc, ImagerColor.ColorFromGray[1.0-intensity]]}; }; DrawWireAssembly: PRIVATE PROC [dc: Imager.Context, assembly: Assembly, scene: Scene, camera: Camera] = { SetColor[dc, camera, Imager.black]; DrawWireAssembly2[dc, assembly, camera]; }; DrawWireAssembly2: PRIVATE PROC [dc: Imager.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: Imager.Context, assembly: Assembly, scene: Scene, camera: Camera] = { <> <> predictedQueueSize: NAT _ CountSurfacesInAssembly[assembly]; surfaceQueue: PriorityQueue.Ref _ PriorityQueue.Predict[predictedQueueSize, DeeperPlanarSurface]; mo: MasterObject; thisPlanarSurf: PlanarSurface; DrawShadedAssemblyAux: SAFE PROC = TRUSTED { <> 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; }; Imager.DoSaveAll[dc, DrawShadedAssemblyAux]; }; 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: Imager.Context, assembly: Assembly, scene: Scene, camera: Camera] = { SetColor[dc, camera, Imager.black]; DrawNormalsAssembly2[dc, assembly, scene, camera]; }; DrawNormalsAssembly2: PROC [dc: Imager.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.