DIRECTORY
AtomButtonsTypes, CoordSys, SVGraphics, Feedback, GList, Imager, ImagerColor, ImagerColorPrivate, ImagerTransformation, IO, Rope, SV2d, SV3d, SVArtwork, SVAssembly, SVBasicTypes, SVBoundBox, SVMasterObject, SVModelTypes, SVScene, SVScenePrivate, SVSceneTypes, SVSelect, SVUtility, ViewerClasses;
Imported Types
BoundBox: TYPE = SVBasicTypes.BoundBox;
Camera: TYPE = SVModelTypes.Camera;
Classification: TYPE = SVSceneTypes.Classification;
Color: TYPE = Imager.Color;
CoordSysList: TYPE = SVModelTypes.CoordSysList;
CoordSystem: TYPE = SVModelTypes.CoordSystem;
CSGTree: TYPE = SVSceneTypes.CSGTree;
DrawStyle: TYPE = SVModelTypes.DrawStyle;
FeedbackData: TYPE = AtomButtonsTypes.FeedbackData;
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 = SVSceneTypes.PointSetOp; -- {union, intersection, difference}
Poly3d: TYPE = SV3d.Poly3d;
Primitive: TYPE = SVSceneTypes.Primitive;
Ray: TYPE = SVSceneTypes.Ray;
Shape: TYPE = SVSceneTypes.Shape;
SliceDescriptor: TYPE = SVSceneTypes.SliceDescriptor;
SliceDescriptorGenerator: TYPE = SVSceneTypes.SliceDescriptorGenerator;
Vector3d: TYPE = SV3d.Vector3d;
Viewer: TYPE = ViewerClasses.Viewer;
DisplayList Types
Databases, Scenes, Assemblies, and Lightsources
Database: TYPE = REF DatabaseObj;
DatabaseObj: TYPE = SVSceneTypes.DatabaseObj;
Scene: TYPE = REF SceneObj;
SceneObj: TYPE = SVSceneTypes.SceneObj;
Artwork: TYPE = SVModelTypes.Artwork;
Slice: TYPE = REF SliceObj;
SliceObj: TYPE = SVSceneTypes.SliceObj;
ToolData: TYPE = REF ToolDataObj;
ToolDataObj: TYPE = SVSceneTypes.ToolDataObj;
SliceList: TYPE = REF SliceListObj;
SliceListObj: TYPE = SVSceneTypes.SliceListObj;
LightSource: TYPE = REF LightSourceObj;
LightSourceObj: TYPE = SVModelTypes.LightSourceObj;
LightSourceList: TYPE = SVModelTypes.LightSourceList;
Master Object Class Types
MasterObjectClass: TYPE = REF MasterObjectClassObj;
MasterObjectClassObj: TYPE = SVSceneTypes.MasterObjectClassObj;
MasterObjectClassList: TYPE = SVSceneTypes.MasterObjectClassList;
FileoutProc: TYPE = SVSceneTypes.FileoutProc;
FileinProc: TYPE = SVSceneTypes.FileinProc;
Master Object Types
MasterObject: TYPE = REF MasterObjectRec;
MasterObjectRec: TYPE = SVSceneTypes.MasterObjectRec;
MasterObjectList: TYPE = SVSceneTypes.MasterObjectList;
FileoutPolyProc: TYPE = SVSceneTypes.FileoutPolyProc;
RayCastProc: TYPE = SVSceneTypes.RayCastProc;
RayCastNoBBoxesProc: TYPE = SVSceneTypes.RayCastNoBBoxesProc;
RayCastBoundingSpheresProc: TYPE = SVSceneTypes.RayCastBoundingSpheresProc;
GetHedronProc: TYPE = SVSceneTypes.GetHedronProc;
PreprocessProc: TYPE = SVSceneTypes.PreprocessProc;
LineDrawProc: TYPE = SVSceneTypes.LineDrawProc;
NormalsDrawProc: TYPE = SVSceneTypes.NormalsDrawProc;
CountSurfProc: TYPE = SVSceneTypes.CountSurfProc;
GetSurfProc:
TYPE = SVSceneTypes.GetSurfProc;
PlanarSurface: TYPE = REF PlanarSurfaceObj;
PlanarSurfaceObj: TYPE = SVSceneTypes.PlanarSurfaceObj;
PlanarSurfaceList: TYPE = SVSceneTypes.PlanarSurfaceList;
DrawPlanarSurfaceProc: TYPE = SVSceneTypes.DrawPlanarSurfaceProc;
DrawSubBoxesProc: TYPE = SVSceneTypes.DrawSubBoxesProc;
DrawSubSpheresProc: TYPE = SVSceneTypes.DrawSubSpheresProc;
Delete Parts of the Scene Tree
DeleteMasterObjectNamed:
PUBLIC
PROC [moName: Rope.
ROPE, scene: Scene]
RETURNS [found:
BOOL] = {
mo, beforeMo, afterMo: MasterObjectList;
[beforeMo, mo, afterMo, found] ← SVScenePrivate.FindMasterObjectAndNeighborsFromName[moName, scene.masterObjects];
IF NOT found THEN RETURN;
IF beforeMo = NIL THEN scene.masterObjects ← afterMo
ELSE beforeMo.rest ← afterMo;
}; -- end of DeleteMasterObjectNamed
MasterObjectIsUsed:
PUBLIC
PROC [mo: MasterObject, scene: Scene]
RETURNS [used:
BOOL] = {
shape: Shape;
IF Rope.Equal[mo.class.name, "sphere"] 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 Slice ←
SVScene.ListOfPrimAssemblies[scene.assembly, scene], primitiveAssemblies.rest
UNTIL primitiveAssemblies =
NIL
DO
shape ← NARROW[primitiveAssemblies.first.shape];
IF shape.mo = mo THEN RETURN[TRUE];
ENDLOOP;
RETURN[FALSE];
};
DeleteMasterObjectIfUnused:
PUBLIC
PROC [mo: MasterObject, scene: Scene]
RETURNS [found:
BOOL] = {
shape: Shape;
For now, we won't delete the built-in instances.
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 Slice ←
SVScene.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] ← SVScenePrivate.FindLightSourceAndNeighborsFromName[lsName, scene.lightSources
!SVScenePrivate.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[SliceListObj ← [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[CoordSys.GetSceneAssembly[world], scene];
};
ClearMasterObjects:
PUBLIC
PROC [scene: Scene] = {
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.
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: Slice, assembly: Slice, scene: Scene]
RETURNS [success:
BOOL] = {
IF ISTYPE[assembly.shape, SliceList] THEN
[assembly.shape, success] ← RemoveFromAssemblyList[subassembly,
NARROW[assembly.shape, SliceList], scene]
ELSE ERROR;
};
RemoveFromAssemblyList:
PROC [a: Slice, al: SliceList, scene: Scene]
RETURNS [newAl: SliceList, success:
BOOL] = {
Tree walk through the assembly deleting all of its coordinate systems. Then, cut the assembly loose and feed it to the garbage collector.
lastAssemblyList: LIST OF Slice ← 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 Slice ← 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: Slice, al: SliceList, scene: Scene]
RETURNS [newAl: SliceList, success:
BOOL] = {
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 SliceList.
lastAssemblyList: LIST OF Slice ← al.list;
IF lastAssemblyList.first = a
THEN {-- first item on the list
al.list ← lastAssemblyList.rest; RETURN[al, TRUE] };
FOR l:
LIST
OF Slice ← 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:
PROC [a: Slice, scene: Scene] = {
DeleteCoordSysAndChildren[a.coordSys, scene];
};
DeleteAllPrimitivesOfClass:
PUBLIC
PROC [className: Rope.
ROPE, scene: Scene, feedback: FeedbackData] = {
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.
moClass: MasterObjectClass;
success: BOOL;
[moClass, success] ← SVMasterObject.FindClassFromName[className];
IF
NOT success
THEN {
Feedback.Append[feedback, Rope.Cat["DeleteAllPrimitivesOfClass: Couldn't find class ", className, "."], oneLiner];
Feedback.Blink[feedback];
};
DeleteAllOfClassAux[moClass, scene.assembly, scene];
};
DeleteAllOfClassAux:
PROC [moClass: MasterObjectClass, root: Slice, scene: Scene] = {
WITH root.shape SELECT FROM
shape: Shape => {
child, parent: Slice;
success: BOOL;
IF shape.mo.class = moClass
THEN {
[child, parent] ← SVScene.FindAssemblyFromName[root.name, scene];
IF child # root THEN ERROR;
success ← SVScene.DeleteSubassemblyFromAssembly[child, parent, scene];
Removes assembly from the assemblyList of superAssembly and deletes the coordinate systems of all of its children.
IF NOT success THEN ERROR;
};
};
alist: SliceList => {
FOR list:
LIST
OF Slice ← alist.list, list.rest
UNTIL list =
NIL
DO
DeleteAllOfClassAux[moClass, list.first, scene];
ENDLOOP;
};
ENDCASE => ERROR;
};
DeleteAllAssembliesSittingOn:
PUBLIC
PROC [chair: Slice, scene: Scene] = {
All assemblies A such that A.sittingOn = chair.name will be deleted along with their children.
DeleteAllSittingOnAux[chair.name, scene.assembly, scene];
};
DeleteAllSittingOnAux:
PROC [chairName: Rope.
ROPE, root: Slice, scene: Scene] = {
child, parent: Slice;
success: BOOL;
IF Rope.Equal[root.sittingOn, chairName,
TRUE]
THEN {
[child, parent] ← SVScene.FindAssemblyFromName[root.name, scene];
IF child # root THEN ERROR;
success ← SVScene.DeleteSubassemblyFromAssembly[child, parent, scene];
Removes assembly from the assemblyList of superAssembly and deletes the coordinate systems of all of its children.
IF NOT success THEN ERROR;
RETURN;
};
WITH root.shape SELECT FROM
shape: Shape => {};
alist: SliceList => {
FOR list:
LIST
OF Slice ← alist.list, list.rest
UNTIL list =
NIL
DO
DeleteAllSittingOnAux[chairName, list.first, scene];
ENDLOOP;
};
ENDCASE => ERROR;
};
We will certainly delete the coincident of all movee's. We may also delete an assembly indirectly referenced by a selection. Worst of all, we may delete an assembly and forget to delete the hooks which are on it. This last may be fixed soon.
DeleteAllSelected:
PUBLIC
PROC [scene: Scene, camera: Camera]
RETURNS [bBox: BoundBox] = {
sliceDescGen: SliceDescriptorGenerator;
assembly, superAssembly: Slice;
success: BOOL ← TRUE;
bBox ← SVBoundBox.BoundBoxOfSelected[scene, camera, normal];
sliceDescGen ← SVSelect.SelectedSlices[scene, normal];
FOR coin: Slice ← SVSelect.NextSlice[sliceDescGen], SVSelect.NextSlice[sliceDescGen]
UNTIL coin =
NIL
DO
[assembly, superAssembly, success] ←
SVScene.FindAssemblyFromName[coin.name, scene];
IF NOT success THEN LOOP;
SVSelect.DeselectEntireSlice[assembly, scene, hot];
success ← SVScene.DeleteSubassemblyFromAssembly[assembly, superAssembly, scene];
Removes assembly from superAssembly; deletes the coordinate systems of its children.
IF NOT success THEN ERROR;
ENDLOOP;
SVSelect.DeselectAll[scene, normal];
};
Copy Parts of the Scene Tree
CopyAssemblyAndSonsRename:
PUBLIC
PROC [assembly: Slice, scene: Scene, prefix: Rope.
ROPE, parent: Slice, feedback: FeedbackData]
RETURNS [copy: Slice] = {
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.
moFound: BOOL;
IF NewNamesAlreadyPresent[assembly, scene, prefix] THEN SIGNAL SVScene.NameAlreadyPresent;
WITH assembly.shape SELECT FROM
alist: SliceList => {
-- assembly is a composite assembly.
copyCS: CoordSystem ← CoordSys.CreateCoordSysInTree[name: Rope.Concat[prefix, assembly.name], mat: CoordSys.GetMat[assembly.coordSys], parent: parent.coordSys, root: scene.coordSysRoot];
copy ← SVAssembly.CreateClusterAssemblyAtExistingCoordSys[Rope.Concat[prefix, assembly.name], alist.pointSetOp, scene, copyCS];
FOR list:
LIST
OF Slice ← alist.list, list.rest
UNTIL list =
NIL
DO
[] ← CopyAssemblyAndSonsRename[list.first, scene,
prefix, copy, feedback];
CopyAssemblyAndSonsRename returns an assembly which is complete and wired up to parent.
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: CoordSys.GetMat[assembly.coordSys], parent: parent.coordSys, root: scene.coordSysRoot];
[copy, moFound] ← SVAssembly.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;
SVAssembly.ConnectAssemblyToParent[copy, parent];
}; -- end of CopyAssemblyAndSons
CopyAssemblyAndSonsNoRename:
PUBLIC
PROC [assembly: Slice, newScene: Scene, parent: Slice, feedback: FeedbackData]
RETURNS [copy: Slice] = {
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.
moFound: BOOL;
IF SVScene.AnyNamesAlreadyPresent[assembly, newScene] THEN SIGNAL SVScene.NameAlreadyPresent;
WITH assembly.shape SELECT FROM
alist: SliceList => {
-- assembly is a composite assembly.
copyCS: CoordSystem ← CoordSys.CreateCoordSysInTree[name: assembly.name, mat: CoordSys.GetMat[assembly.coordSys], parent: parent.coordSys, root: newScene.coordSysRoot];
copy ← SVAssembly.CreateClusterAssemblyAtExistingCoordSys[assembly.name, alist.pointSetOp, newScene, copyCS];
FOR list:
LIST
OF Slice ← alist.list, list.rest
UNTIL list =
NIL
DO
[] ← CopyAssemblyAndSonsNoRename[list.first, newScene, copy, feedback];
CopyAssemblyAndSonsNoRename returns an assembly which is complete and wired up to parent.
ENDLOOP;
};
shape: Shape => {
-- assembly is a primitive assembly
artworkCopy: Artwork ← SVArtwork.Copy[assembly.artwork];
copyCS: CoordSystem ← CoordSys.CreateCoordSysInTree[name: assembly.name, mat: CoordSys.GetMat[assembly.coordSys], parent: parent.coordSys, root: newScene.coordSysRoot];
[copy, moFound] ← SVAssembly.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;
SVAssembly.ConnectAssemblyToParent[assembly, parent];
}; -- end of CopyAssemblyAndSonsNoRename
ReadAlpha:
PROC [s:
IO.
STREAM]
RETURNS [base: Rope.
ROPE] = {
skip: INT;
[base, skip] ← IO.GetTokenRope[s, AlphaBreakProc];
};
AlphaBreakProc:
SAFE
PROC [char:
CHAR]
RETURNS [
IO.CharClass] = {
RETURN[IF char = '. THEN break ELSE other]
};
FindUniqueAssemblyNum:
PROC [scene: Scene]
RETURNS [num:
NAT] = {
num ← FindUniqueAssemblyNumAux[scene.assembly];
num ← num + 1;
};
FindUniqueAssemblyNumAux:
PROC [assembly: Slice]
RETURNS [num:
NAT] = {
Finds an integer such that "<name>.<num>" is unique in the scene of assembly for all strings <name>. i.e. Find the highest .num extension in the tree rooted at assembly.
thisNum: NAT;
WITH assembly.shape SELECT FROM
alist: SliceList => {
-- assembly is a composite assembly.
[----, num] ← CoordSys.BaseAndNumber[assembly.name];
FOR l:
LIST
OF Slice ← 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: Slice, oldScene: Scene, newScene: Scene, parent: Slice, feedback: FeedbackData]
RETURNS [copy: Slice] = {
oldScene is the scene assembly belongs to. newScene is the scene copy will belong to. parent must be an assembly in the new scene.
num: NAT;
success: BOOL;
num ← FindUniqueAssemblyNum[newScene];
IF oldScene = newScene
THEN
copy ← CopyAssemblyAndSonsUniqueNamesAux[assembly, newScene, parent, num, feedback]
ELSE {
success ← CopyNeededMasterObjects[assembly, oldScene, newScene];
IF
NOT success
THEN {
Feedback.Append[feedback, Rope.Cat["Masterobject name conflict scenes: ", oldScene.name, "/", newScene.name], oneLiner];
Feedback.Blink[feedback];
RETURN;
};
copy ← CopyAssemblyAndSonsUniqueNamesAux[assembly, newScene, parent, num, feedback];
};
};
CopyAssemblyAndSonsUniqueNamesAux:
PUBLIC
PROC [assembly: Slice, newScene: Scene, parent: Slice, num:
NAT, feedback: FeedbackData]
RETURNS [copy: Slice] = {
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.
thisBase, unique: Rope.ROPE;
thisNum: NAT;
moFound: BOOL;
WITH assembly.shape SELECT FROM
alist: SliceList => {
-- assembly is a composite assembly.
copyCS: CoordSystem;
[thisBase, thisNum] ← CoordSys.BaseAndNumber[assembly.name];
unique ← IO.PutFR["%g.%g", [rope[thisBase]], [integer[num]]];
copyCS ← CoordSys.CreateCoordSysInTree[name: unique,
mat: CoordSys.GetMat[assembly.coordSys],
parent: parent.coordSys,
root: newScene.coordSysRoot];
copy ← SVAssembly.CreateClusterAssemblyAtExistingCoordSys[unique, alist.pointSetOp, newScene, copyCS];
FOR list:
LIST
OF Slice ← alist.list, list.rest
UNTIL list =
NIL
DO
[] ← CopyAssemblyAndSonsUniqueNamesAux[list.first, newScene, copy, num, feedback];
ENDLOOP;
};
shape: Shape => {
-- assembly is a primitive assembly
artworkCopy: Artwork ← SVArtwork.Copy[assembly.artwork];
copyCS: CoordSystem;
oldMO, newMO: MasterObject;
[thisBase, thisNum] ← CoordSys.BaseAndNumber[assembly.name];
unique ← IO.PutFR["%g.%g",[rope[thisBase]], [integer[num]]];
copyCS ← CoordSys.CreateCoordSysInTree[
name: unique,
mat: CoordSys.GetMat[assembly.coordSys],
parent: parent.coordSys,
root: newScene.coordSysRoot];
oldMO ← shape.mo;
newMO ← oldMO.class.copy[oldMO, unique];
SVScene.AddMasterObjectToScene[newMO, newScene];
[copy, moFound] ← SVAssembly.CreatePrimitiveAtExistingCoordSys[unique, newMO.name, CoordSys.GetScalars[shape.coordSys], newScene, copyCS, artworkCopy, assembly.isTool];
IF NOT moFound THEN ERROR;
};
ENDCASE => ERROR;
SVAssembly.ConnectAssemblyToParent[copy, parent];
};
AddMOsToScene:
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 ← SVUtility.AppendToMasterObjects[list.first, scene.masterObjects];
ENDLOOP;
};
CopyMOList:
PROC [moList: MasterObjectList]
RETURNS [copyList: MasterObjectList] = {
copyList ← NIL;
FOR list: MasterObjectList ← moList, list.rest
UNTIL list =
NIL
DO
copyList ← SVUtility.AppendToMasterObjects[SVScene.CopyMasterObject[list.first], copyList];
ENDLOOP;
};
CopyNeededMasterObjects:
PUBLIC
PROC [assembly: Slice, fromScene, toScene: Scene]
RETURNS [success:
BOOL] = {
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.
moList: MasterObjectList;
toMoList: MasterObjectList;
neededList: MasterObjectList;
success ← TRUE;
moList ← SVScene.MasterObjectsOfAssembly[assembly, fromScene];
toMoList ← SVScene.MasterObjectsOfScene[toScene];
neededList ← SVScenePrivate.MoListMinusMoList[moList, toMoList];
neededList ← CopyMOList[neededList];
AddMOsToScene[neededList, toScene];
};
Draw Parts of the Scene Tree
DrawScene:
PUBLIC
PROC [dc: Imager.Context, scene: Scene, camera: Camera, except: Slice ←
NIL] = {
DrawSceneAux:
SAFE PROC = {
SVGraphics.Clip[dc, camera];
SELECT camera.style
FROM
wire => DrawWireAssemblies[dc, scene, camera];
shaded => DrawShadedAssemblies[dc, scene, camera, clippedBy, except];
normals => DrawNormalsAssemblies[dc, scene, camera];
ENDCASE => SIGNAL NotYetImplemented;
Draw the current bounding frame if there is one.
IF
NOT camera.frame.fullScreen
THEN {
SetColor[dc, camera, Imager.black];
SVGraphics.DrawFrame[dc, camera];
};
};
clippedBy: Imager.Rectangle ← [0.0, 0.0, 8.5*72.0, 11.0*72.0];
Imager.DoSaveAll[dc, DrawSceneAux];
};
NotYetImplemented: PUBLIC SIGNAL = CODE;
DrawWireAssemblies:
PROC [dc: Imager.Context, scene: Scene, camera: Camera] = {
assemblyName: Rope.ROPE;
found: BOOL;
assembly: Slice;
FOR list:
LIST
OF Rope.
ROPE ← camera.visibleAssemblies, list.rest
UNTIL list =
NIL
DO
assemblyName ← list.first;
found ← TRUE;
[assembly, ----] ← SVScene.FindAssemblyFromName[assemblyName, scene
!SVScene.AssemblyNotFound => {found ← FALSE; CONTINUE}];
IF found
THEN {
SVAssembly.Draw[assembly, dc, scene, camera];
};
ENDLOOP;
};
DrawShadedAssemblies:
PROC [dc: Imager.Context, scene: Scene, camera: Camera, clippedBy: Imager.Rectangle, except: Slice ←
NIL] = {
assemblyName: Rope.ROPE;
assembly: Slice;
found: BOOL;
Draw a background color.
SetColor[dc, camera, scene.backgroundColor];
Imager.MaskRectangle[dc, clippedBy];
FOR list:
LIST
OF Rope.
ROPE ← camera.visibleAssemblies, list.rest
UNTIL list =
NIL
DO
assemblyName ← list.first;
found ← TRUE;
[assembly, ----] ← SVScene.FindAssemblyFromName[assemblyName, scene
!SVScene.AssemblyNotFound => {found ← FALSE; CONTINUE}];
IF found
THEN {
SVAssembly.Draw[assembly, dc, scene, camera];
};
ENDLOOP;
};
DrawNormalsAssemblies:
PROC [dc: Imager.Context, scene: Scene, camera: Camera] = {
assemblyName: Rope.ROPE;
assembly: Slice;
found: BOOL;
FOR list:
LIST
OF Rope.
ROPE ← camera.visibleAssemblies, list.rest
UNTIL list =
NIL
DO
assemblyName ← list.first;
found ← TRUE;
[assembly, ----] ← SVScene.FindAssemblyFromName[assemblyName, scene
!SVScene.AssemblyNotFound => {found ← FALSE; CONTINUE}];
IF found
THEN {
SVAssembly.Draw[assembly, dc, scene, camera];
};
ENDLOOP;
};
SetColor:
PROC [dc: Imager.Context, camera: Camera, color: Color] = {
IF camera.colorFilm THEN Imager.SetColor[dc, color]
ELSE {
intensity: REAL ← ImagerColorPrivate.IntensityFromColor[NARROW[color]];
Imager.SetColor[dc, ImagerColor.ColorFromGray[1.0-intensity]]};
};