Imported Types
Artwork: TYPE = REF ArtworkObj;
ArtworkObj: TYPE = SVArtwork.ArtworkObj;
Camera: TYPE = REF CameraObj;
CameraObj: TYPE = CSGGraphics.CameraObj;
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;
DrawStyle: TYPE = CSGGraphics.DrawStyle;
FrameBox: TYPE = REF FrameBoxObj;
FrameBoxObj: TYPE = CSGGraphics.FrameBoxObj;
Matrix4by4: TYPE = Matrix3d.Matrix4by4;
Plane: TYPE = SVPolygon3d.Plane;
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;
DisplayList Types
Databases, Scenes, Assemblies, and Lightsources
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;
FileCamera: TYPE = REF FileCameraObj;
FileCameraObj: TYPE = DisplayList3d.FileCameraObj;
FileCameraList: TYPE = DisplayList3d.FileCameraList;
Master Object Class Types
MasterObjectClass: TYPE = REF MasterObjectClassObj;
MasterObjectClassObj: TYPE = DisplayList3d.MasterObjectClassObj;
MasterObjectClassList: TYPE = DisplayList3d.MasterObjectClassList;
FileoutProc: TYPE = DisplayList3d.FileoutProc;
FileinProc: TYPE = DisplayList3d.FileinProc;
Master Object Types
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;
Global Variables
globalDatabase: Database;
globalClassList: MasterObjectClassList ← NIL;
globalMOList: MasterObjectList ← NIL;
Set Up the System
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];
};
Create Entities
CreateScene:
PUBLIC
PROC [name: Rope.
ROPE]
RETURNS [scene: Scene] = {
Creates scene and adds scene to database. Includes default coordinate systems (WORLD, CAMERA, and SCENE), one default light source, five default master objects (cube, sphere, cone, cylinder, and torus) and seven default cameras (Top, Bottom, Left, Right, Front, UpLeft, and UpRight).
initialCS: CoordSysList ← CoordSys.InitialCoordSysList[];
worldCS: CoordSystem ← CoordSys.FindCoordSysFromName["WORLD", initialCS];
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];
cameras: FileCameraList ← DisplayList3d.InitialCameraList[];
scene ←
NEW[SceneObj ← [
name: name,
worldCS: worldCS,
coordSystems: initialCS,
lightSources: CONS[defaultWhiteLight, NIL],
masterObjects: DisplayList3dPrivate.CopyMasterObjectList[globalMOList], -- Copies the list structure but not the objects.
assembly: sceneAssembly,
cameras: cameras,
cameraOrder: LIST["Front"],
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] = {
Creates scene and adds scene to database.
scene ←
NEW[SceneObj ← [name: name,
worldCS: NIL,
coordSystems: NIL, lightSources: NIL,
masterObjects: NIL,
assembly: NIL,
cameras: NIL,
cameraOrder: 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] = {
Adds the named object to the scene's master object list.
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] = {
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.
vector: Vector ← position;
ls ← NEW[LightSourceObj ← [name, position, color]];
};
CreateFileCamera:
PUBLIC
PROC [name: Rope.
ROPE, origin: Point3d, focusPoint: Point3d, slant:
REAL, resolution:
REAL, focalLength:
REAL, clippingPlanes:
LIST
OF Plane, visibleAssemblies:
LIST
OF Rope.
ROPE]
RETURNS [fileCamera: FileCamera] = {
frameBox: FrameBox ← NEW[FrameBoxObj ← [[0,0], [0,0], TRUE]];
fileCamera ← NEW[FileCameraObj ← [name, origin, focusPoint, slant, resolution, focalLength, frameBox, clippingPlanes, visibleAssemblies]];
};
CameraFromFileCamera:
PUBLIC
PROC [fileCamera: FileCamera, worldCS: CoordSystem, screenCS: CoordSystem, style: DrawStyle]
RETURNS [camera: Camera] = {
A conversion from the viewer-independent to the viewer-dependent type of camera.
colorFilm: BOOL ← TRUE;
abort: BOOL ← FALSE;
coordSys: CoordSystem ← CoordSys.CreateCoordSys[name: fileCamera.name, mat: Matrix3d.Identity[], withRespectTo: worldCS]; -- to start with
camera ← NEW[CameraObj ← [fileCamera.name, coordSys, screenCS, fileCamera.resolution, fileCamera.focalLength, fileCamera.frame, fileCamera.clippingPlanes, fileCamera.visibleAssemblies, style, colorFilm, fast, abort]];
CSGGraphics.PlaceCamera[camera, fileCamera.focusPoint, fileCamera.origin, fileCamera.slant];
};
InitialCameraList:
PUBLIC
PROC []
RETURNS [cameras: FileCameraList] = {
An initial list of cameras provided with a new scene (or an old scene which was made before named file cameras were introduced).
topMat, bottomMat, leftMat, rightMat, frontMat, upLeftMat, upRightMat: Matrix4by4;
top, bottom, left, right, front, upLeft, upRight: FileCamera;
defaultFocalLength: REAL = 1800;
defaultResolution: REAL ← 72.0;
hither: Plane ← SVPolygon3d.PlaneFromPointAndNormal[[0,0,0], [0,0,1]];
sAList: LIST OF Rope.ROPE ← LIST["sceneAssembly"];
topMat ← Matrix3d.MatMult[Matrix3d.MakeRotateXMat[90], Matrix3d.MakeTranslateMat[0,0,1800]];
bottomMat ← Matrix3d.MatMult[Matrix3d.MakeRotateXMat[-90], Matrix3d.MakeTranslateMat[0,0,1800]];
leftMat ← Matrix3d.MatMult[Matrix3d.MakeRotateYMat[-90], Matrix3d.MakeTranslateMat[0,0,1800]];
rightMat ← Matrix3d.MatMult[Matrix3d.MakeRotateYMat[90], Matrix3d.MakeTranslateMat[0,0,1800]];
frontMat ← Matrix3d.MakeTranslateMat[0,0,1800];
upLeftMat ← Matrix3d.MatMult[Matrix3d.MakeRotateYMat[-20], Matrix3d.MakeTranslateMat[0,0,1800]];
upLeftMat ← Matrix3d.MatMult[Matrix3d.MakeRotateXMat[20], upLeftMat];
upRightMat ← Matrix3d.MatMult[Matrix3d.MakeRotateYMat[20], Matrix3d.MakeTranslateMat[0,0,1800]];
upRightMat ← Matrix3d.MatMult[Matrix3d.MakeRotateXMat[20], upRightMat];
top ← CreateFileCamera[name: "Top", origin: [0,1800,0], focusPoint: [0,0,0], slant: 0, resolution: defaultResolution, focalLength: defaultFocalLength, clippingPlanes: LIST[hither], visibleAssemblies: sAList];
bottom ← CreateFileCamera[name: "Bottom", origin: [0,-1800,0], focusPoint: [0,0,0], slant: 0, resolution: defaultResolution, focalLength: defaultFocalLength, clippingPlanes: LIST[hither], visibleAssemblies: sAList];
left ← CreateFileCamera[name: "Left", origin: [-1800,0,0], focusPoint: [0,0,0], slant: 0, resolution: defaultResolution, focalLength: defaultFocalLength, clippingPlanes: LIST[hither], visibleAssemblies: sAList];
right ← CreateFileCamera[name: "Right", origin: [1800,0,0], focusPoint: [0,0,0], slant: 0, resolution: defaultResolution, focalLength: defaultFocalLength, clippingPlanes: LIST[hither], visibleAssemblies: sAList];
front ← CreateFileCamera[name: "Front", origin: [0,0,1800], focusPoint: [0,0,0], slant: 0, resolution: defaultResolution, focalLength: defaultFocalLength, clippingPlanes: LIST[hither], visibleAssemblies: sAList];
upLeft ← CreateFileCamera[name: "UpLeft", origin: [-600,1200,1800], focusPoint: [0,0,0], slant: 0, resolution: defaultResolution, focalLength: defaultFocalLength, clippingPlanes: LIST[hither], visibleAssemblies: sAList];
upRight ← CreateFileCamera[name: "UpRight", origin: [600,1200,1800], focusPoint: [0,0,0], slant: 0, resolution: defaultResolution, focalLength: defaultFocalLength, clippingPlanes: LIST[hither], visibleAssemblies: sAList];
cameras ← LIST[top, bottom, left, right, front, upLeft, upRight];
};
Build the Scene Tree
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];
};
AddCameraToScene:
PUBLIC PROC [fileCamera: FileCamera, scene: Scene] = {
IF FileCameraNameIsPresent[fileCamera.name, scene] THEN SIGNAL NameAlreadyPresent;
scene.cameras ← AppendToFileCameraList[fileCamera, scene.cameras];
};
AddCameraOrderNameToScene:
PUBLIC PROC [name: Rope.
ROPE, scene: Scene] = {
The names of those cameras which should open automatically with the pic file is loaded are added to the scene in order.
IF CameraOrderNameIsPresent[name, scene] THEN SIGNAL NameAlreadyPresent;
scene.cameraOrder ← AppendToCameraOrderList[name, scene.cameraOrder];
};
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] = {
Add assembly to the top level list of assemblies in the current scene
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] = {
Automatically makes coordsys of subassembly refer to coordsys of super assembly.
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;
};
List Append Auxiliaries For the Add Procedures
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];
};
AppendToFileCameraList:
PROC [fileCamera: FileCamera, list: FileCameraList]
RETURNS [FileCameraList] = {
A copy of List.Nconc1 for CoordSysList instead of LIST OF REF ANY
z: FileCameraList ← list;
IF z = NIL THEN RETURN[CONS[fileCamera,NIL]];
UNTIL z.rest = NIL DO z ← z.rest; ENDLOOP;
z.rest ← CONS[fileCamera,NIL];
RETURN[list];
};
AppendToCameraOrderList:
PROC [name: Rope.
ROPE, list:
LIST
OF Rope.
ROPE]
RETURNS [
LIST
OF Rope.
ROPE] = {
A copy of List.Nconc1 for LIST OF Rope.ROPE instead of LIST OF REF ANY
z: LIST OF Rope.ROPE ← list;
IF z = NIL THEN RETURN[CONS[name,NIL]];
UNTIL z.rest = NIL DO z ← z.rest; ENDLOOP;
z.rest ← CONS[name,NIL];
RETURN[list];
};
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:
PUBLIC 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];
};
Restructure the Tree
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];
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.
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];
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.
thisA.coordSys.mat ← list.first.coordSys.mat;
AddSubassemblyToAssemblyWithCS[thisA, assembly, newScene, thisA.coordSys];
ENDLOOP;
};
MoveSubassembly:
PUBLIC
PROC [assem: Assembly, to: Assembly, scene: Scene] = {
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.
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;
Remove links from parent to assembly.
parentList ← NARROW[parent.object];
[parent.object, found] ← DisplayList3dPrivate.TemporaryRemoveFromAssemblyList[assem, parentList, scene];
IF
NOT found
THEN
ERROR;
-- it was found just a few lines ago. What happened?
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.
[] ← CoordSys.TPutAinTermsOfB[assem.coordSys, to.coordSys];
Create link from 'to' to assem.
to.object ← AppendToAssemblyList[assem, NARROW[to.object]]
}; -- end of MoveSubassembly
MoveToFrontOfAssembly:
PUBLIC
PROC [subassembly: Assembly, assembly: Assembly, scene: Scene] = {
Moves subassembly to the first position of assembly's assemblylist.
Make sure "subassembly" is a subassembly of "assembly".
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] ← DisplayList3dPrivate.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] = {
We assume that none of the mo's in moList is already in 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] = {
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.
moList: MasterObjectList ← MasterObjectsOfAssembly[newAssembly, fromScene];
toMoList: MasterObjectList ← MasterObjectsOfScene[toScene];
neededList: MasterObjectList ← DisplayList3dPrivate.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] = {
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.
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;
};
Find Scene Entities from their Names
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] = {
Finds the named assembly and its immediate superior. superAssembly is NIL if assembly is top level.
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];
};
FindFileCameraFromName:
PUBLIC
PROC [name: Rope.
ROPE, scene: Scene]
RETURNS [fileCamera: FileCamera, success:
BOOL] = {
FOR list: FileCameraList ← scene.cameras, list.rest
UNTIL list =
NIL
DO
IF Rope.Equal[list.first.name, name, TRUE] THEN RETURN [list.first, TRUE];
ENDLOOP;
RETURN [NIL, FALSE];
};
FileCameraNameIsPresent:
PUBLIC
PROC [name: Rope.
ROPE, scene: Scene]
RETURNS [
BOOL] = {
FOR list: FileCameraList ← scene.cameras, list.rest
UNTIL list =
NIL
DO
IF Rope.Equal[list.first.name, name, TRUE] THEN RETURN [TRUE];
ENDLOOP;
RETURN[FALSE];
};
CameraOrderNameIsPresent:
PUBLIC
PROC [name: Rope.
ROPE, scene: Scene]
RETURNS [
BOOL] = {
FOR list:
LIST
OF Rope.
ROPE ← scene.cameraOrder, list.rest
UNTIL list =
NIL
DO
IF Rope.Equal[list.first, name, TRUE] THEN RETURN [TRUE];
ENDLOOP;
RETURN[FALSE];
};
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:
PUBLIC
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:
PUBLIC
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: PUBLIC SIGNAL = CODE;
Get Generators of Scene Entities
Scene Generator
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;
};
CoordSystem Generator
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;
};
Assembly Generator
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;
};
LightSource Generator
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;
};
MasterObject Generator
MasterObjectsOfScene:
PUBLIC
PROC [scene: Scene]
RETURNS [l: MasterObjectList] = {
l ← scene.masterObjects;
};
MasterObjectsOfAssembly:
PUBLIC
PROC [assembly: Assembly, scene: Scene]
RETURNS [l: MasterObjectList] = {
Get a list of the leaves of the tree and extract a master object from each. Remove duplicates.
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 ← DisplayList3dPrivate.RemoveDuplicateMOs[l];
};
List of Primitive Assemblies
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]];
};