File: BasicObject3dImpl.mesa
Last edited by: Eric Bier on February 2, 1987 1:38:00 pm PST
Copyright © 1984 by Xerox Corporation. All rights reserved.
Contents: Defines a simple set of objects which can be display with ray casting, line drawing, or shaded planar-surface approximation.
DIRECTORY
BasicObject3d, CoordSys, Imager, IO, Matrix3d, ObjectCast, PredefSweeps, Rope, SV2d, SV3d, SVBasicTypes, SVBoundBox, SVBoundSphere, SVDraw3d, SVFaces, SVModelTypes, SVPolygon2d, SVPolygon3d, SVRayTypes, SVScene, SVSceneTypes, SweepCast, SweepGeometry, TFI3d, TFO3d;
BasicObject3dImpl:
CEDAR PROGRAM
IMPORTS CoordSys, SVScene, IO, Matrix3d, ObjectCast, PredefSweeps, SVBoundBox, SVBoundSphere, SVDraw3d, SVPolygon2d, SVPolygon3d, SweepCast, SweepGeometry, TFI3d, TFO3d
EXPORTS BasicObject3d =
BEGIN
GENERAL TYPES
BoundHedron: TYPE = SVBasicTypes.BoundHedron;
Camera: TYPE = SVModelTypes.Camera;
Cone: TYPE = SVFaces.Cone;
Cylinder: TYPE = SVFaces.Cylinder;
DiskRing: TYPE = SVFaces.DiskRing;
LinearMesh: TYPE = REF LinearMeshRecord;
LinearMeshArray: TYPE = SweepGeometry.LinearMeshArray;
LinearMeshRecord: TYPE = SweepGeometry.LinearMeshRecord;
Matrix4by4: TYPE = SV3d.Matrix4by4;
Path: TYPE = SV2d.Path;
Point2d: TYPE = SV2d.Point2d;
Poly3d: TYPE = SV3d.Poly3d;
Polygon: TYPE = SV2d.Polygon;
RevoFace: TYPE = SweepCast.RevoFace;
RevoluteMesh: TYPE = REF RevoluteMeshRecord;
RevoluteMeshArray: TYPE = SweepGeometry.RevoluteMeshArray;
RevoluteMeshRecord: TYPE = SweepGeometry.RevoluteMeshRecord;
Shape: TYPE = SVSceneTypes.Shape;
SubBoxesBody: TYPE = REF SubBoxesBodyObj;
SubBoxesBodyObj: TYPE = SweepCast.SubBoxesBodyObj;
SubSpheresBody: TYPE = REF SubSpheresBodyObj;
SubSpheresBodyObj: TYPE = SweepCast.SubSpheresBodyObj;
ToroidalMesh: TYPE = REF ToroidalMeshRecord;
ToroidalMeshRecord: TYPE = SweepGeometry.ToroidalMeshRecord;
SHADING TYPES
BoundBox: TYPE = SVBasicTypes.BoundBox;
CoordSystem: TYPE = SVModelTypes.CoordSystem;
LightSourceList: TYPE = SVModelTypes.LightSourceList;
PlanarSurface: TYPE = SVSceneTypes.PlanarSurface;
PlanarSurfaceList: TYPE = SVSceneTypes.PlanarSurfaceList;
RAY CASTING TYPES
Assembly: TYPE = SVSceneTypes.Assembly;
Classification: TYPE = SVRayTypes.Classification;
Composite: TYPE = SVRayTypes.Composite;
MasterObject: TYPE = SVSceneTypes.MasterObject;
MasterObjectClass: TYPE = SVSceneTypes.MasterObjectClass;
MasterObjectClassList: TYPE = SVSceneTypes.MasterObjectClassList; -- LIST OF MasterObjectClass
Primitive: TYPE = SVRayTypes.Primitive;
Ray: TYPE = SVRayTypes.Ray;
RayCastProc: TYPE = SVRayTypes.RayCastProc;
PreprocessProc: TYPE = SVSceneTypes.PreprocessProc;
LineDrawProc: TYPE = SVSceneTypes.LineDrawProc;
NormalsDrawProc: TYPE = SVSceneTypes.NormalsDrawProc;
CountPlanarSurfacesProc: TYPE = SVSceneTypes.CountPlanarSurfacesProc;
GetPlanarSurfacesProc: TYPE = SVSceneTypes.GetPlanarSurfacesProc;
DrawPlanarSurfaceProc: TYPE = SVSceneTypes.DrawPlanarSurfaceProc;
DrawSubBoxesProc: TYPE = SVSceneTypes.DrawSubBoxesProc;
SurfaceArray: TYPE = REF SurfaceArrayObj;
SurfaceArrayObj: TYPE = SVRayTypes.SurfaceArrayObj;
RectSurface: TYPE = REF RectSurfaceObj;
RectSurfaceObj: TYPE = ObjectCast.RectSurfaceObj;
TubeSurface: TYPE = REF TubeSurfaceObj;
TubeSurfaceObj: TYPE = ObjectCast.TubeSurfaceObj;
DiskSurface: TYPE = REF DiskSurfaceObj;
DiskSurfaceObj: TYPE = ObjectCast.DiskSurfaceObj;
ShellSurface: TYPE = REF ShellSurfaceObj;
ShellSurfaceObj: TYPE = ObjectCast.ShellSurfaceObj;
ConeSurface: TYPE = REF ConeSurfaceObj;
ConeSurfaceObj: TYPE = ObjectCast.ConeSurfaceObj;
ToroidalSurface: TYPE = REF ToroidalSurfaceObj;
ToroidalSurfaceObj: TYPE = ObjectCast.ToroidalSurfaceObj;
Basic Object Shapes
SphereRec: TYPE = REF SphereRecObj;
SphereRecObj: TYPE = BasicObject3d.SphereRecObj;
BlockRec: TYPE = REF BlockRecObj;
BlockRecObj: TYPE = BasicObject3d.BlockRecObj;
CylinderRec: TYPE = REF CylinderRecObj;
CylinderRecObj: TYPE = BasicObject3d.CylinderRecObj;
ConeRec: TYPE = REF ConeRecObj;
ConeRecObj: TYPE = BasicObject3d.ConeRecObj;
TorusRec: TYPE = REF TorusRecObj;
TorusRecObj: TYPE = BasicObject3d.TorusRecObj;
RevoSweepRec: TYPE = REF RevoSweepRecObj;
RevoSweepRecObj:
TYPE =
RECORD [
path: Path
];
GLOBAL VARIABLES
sphereClass, blockClass, cylinderClass, coneClass, torusClass, linClass, revoClass: MasterObjectClass;
WrongTypeOfData: PUBLIC SIGNAL = CODE;
SphereBody:
PROC
RETURNS [sphereRec: SphereRec] = {
sphereRec ← NEW[SphereRecObj];
sphereRec.radius ← 1;
};
SphereMakeMasterObject:
PUBLIC
PROC [name: Rope.
ROPE]
RETURNS [mo: MasterObject] = {
mainBody: SphereRec ← SphereBody[];
lineBody: REF ANY ← PredefSweeps.GetUnitSphere[];
shadeBody: REF ANY ← lineBody;
rayCastBody: REF ANY ← SphereGetRayCastBody[];
mo ← SVScene.CreateMasterObject[name, sphereClass, mainBody, lineBody, shadeBody, rayCastBody];
};
SphereUpdate:
PUBLIC
PROC [mo: MasterObject, updateData:
REF
ANY] = {
mo.lineBody ← PredefSweeps.GetUnitSphere[];
mo.shadeBody ← mo.lineBody;
mo.rayCastBody ← SphereGetRayCastBody[];
};
SphereBoundHedron:
PUBLIC
PROC [mo: MasterObject]
RETURNS [hedron: BoundHedron] = {
hedron ← SVBoundBox.HexagonalBoundHedron[1, 1];
};
SphereGetRayCastBody:
PROC []
RETURNS [shellS: ShellSurface] = {
shellS ← NEW[ShellSurfaceObj];
};
SphereRayCast:
PUBLIC
PROC [cameraPoint: Point2d, localRay: Ray, masterObject:
REF
ANY, prim: Primitive]
RETURNS [class: Classification] = {
mo: MasterObject ← NARROW[masterObject];
RETURN[ObjectCast.SphereCast[localRay, NARROW[mo.rayCastBody], prim]];
};
SphereRayCastNoBBoxes:
PUBLIC
PROC [localRay: Ray, masterObject:
REF
ANY, prim: Primitive]
RETURNS [class: Classification] = {
mo: MasterObject ← NARROW[masterObject];
RETURN[ObjectCast.SphereCast[localRay, NARROW[mo.rayCastBody], prim]];
};
SphereRayCastBoundingSpheres:
PUBLIC
PROC [localRay: Ray, masterObject:
REF
ANY, prim: Primitive]
RETURNS [class: Classification] = {
mo: MasterObject ← NARROW[masterObject];
RETURN[ObjectCast.SphereCast[localRay, NARROW[mo.rayCastBody], prim]];
};
SphereLineDraw:
PUBLIC
PROC[dc: Imager.Context, data:
REF
ANY, camera: Camera, localCS: CoordSystem] = {
revMesh: RevoluteMesh;
IF ISTYPE[data, RevoluteMesh]
THEN revMesh ← NARROW[data]
ELSE SIGNAL WrongTypeOfData;
SweepGeometry.LineDrawRevoluteSweep[dc, revMesh, camera, localCS];
};
OldSphereDrawNormals: PUBLIC PROC[dc: Imager.Context, data: REF ANY, camera: Camera, localCS: CoordSystem] = {
revMesh: RevoluteMesh;
IF ISTYPE[data, RevoluteMesh]
THEN revMesh ← NARROW[data]
ELSE SIGNAL WrongTypeOfData;
SweepGeometry.DrawNormalsRevoluteSweep[dc, revMesh, camera, localCS];
};
SphereDrawNormals:
PUBLIC
PROC[dc: Imager.Context, data:
REF
ANY, camera: Camera, localCS: CoordSystem] = {
CirclePath: Imager.PathProc = {
moveTo[[-1.0, 0.0]];
arcTo[[1.0, 0.0], [-1.0, 0.0]];
};
revMesh: RevoluteMesh;
linesOfLatitude, linesOfLongitude: NAT;
deltaTheta: REAL;
transform, csCamera: Matrix4by4;
IF ISTYPE[data, RevoluteMesh]
THEN revMesh ← NARROW[data]
ELSE SIGNAL WrongTypeOfData;
linesOfLatitude ← revMesh.linesOfLatitude;
linesOfLongitude ← revMesh.linesOfLongitude;
transform ← csCamera ← CoordSys.FindInTermsOfCamera[localCS, camera.coordSys];
SVDraw3d.DrawTransformedShape[dc: dc, csCAMERA: transform, camera: camera, path: CirclePath];
deltaTheta ← 360.0/linesOfLongitude;
FOR i:
NAT
IN [1..linesOfLongitude-1]
DO
transform ← Matrix3d.LocalRotateAboutYAxis[transform, deltaTheta];
SVDraw3d.DrawTransformedShape[dc: dc, csCAMERA: transform, camera: camera, path: CirclePath];
ENDLOOP;
transform ← csCamera;
transform ← Matrix3d.LocalRotateAboutXAxis[transform, 90];
SVDraw3d.DrawTransformedShape[dc: dc, csCAMERA: transform, camera: camera, path: CirclePath];
FOR j: NAT IN [1..linesOfLatitude-1] DO
ENDLOOP;
SphereCountSurf:
PUBLIC
PROC [masterObject: MasterObject]
RETURNS [len:
NAT] = {
revMesh: RevoluteMesh ← NARROW[masterObject.shadeBody];
len ← SweepGeometry.CountPlanarSurfacesRevoluteSweep[revMesh];
};
SphereCountVert:
PUBLIC
PROC [masterObject: MasterObject]
RETURNS [len:
NAT] = {
revMesh: RevoluteMesh ← NARROW[masterObject.shadeBody];
len ← SweepGeometry.CountVerticesRevoluteSweep[revMesh];
};
SphereGetSurf:
PUBLIC
PROC [assembly: Assembly, camera: CoordSystem]
RETURNS [psl: PlanarSurfaceList] = {
shape: Shape ← NARROW[assembly.shape];
masterObject: MasterObject ← shape.mo;
revMesh: RevoluteMesh ← NARROW[masterObject.shadeBody];
psl ← SweepGeometry.PlanarSurfacesRevoluteSweep[revMesh, assembly, camera];
};
SphereDrawSurf:
PUBLIC
PROC [dc: Imager.Context, ps: PlanarSurface, lightSources: LightSourceList, camera: Camera] = {
SweepGeometry.DrawPlanarSurfaceRevoluteSweep[dc, ps, lightSources, camera];
};
SphereFilein:
PUBLIC
PROC [f:
IO.
STREAM, name: Rope.
ROPE]
RETURNS [mo: MasterObject] = {
TFI3d.ReadRope[f, "data: procedural"];
TFI3d.ReadBlank[f];
mo ← SphereMakeMasterObject[name];
};
SphereFileout:
PUBLIC
PROC [f:
IO.
STREAM, mo: MasterObject] = {
Spheres can be recovered from scratch.
f.PutChar[IO.TAB];
f.PutF["data: procedural\n"];
};
SphereFileoutPoly:
PUBLIC
PROC [f:
IO.
STREAM, mo: MasterObject] = {
revMesh: RevoluteMesh ← NARROW[mo.shadeBody];
SweepGeometry.PolyListRevolute[f, revMesh];
};
BlockBody:
PROC
RETURNS [blockRec: BlockRec] = {
blockRec ← NEW[BlockRecObj];
blockRec.x ← 2; blockRec.y ← 2; blockRec.z ← 2;
};
BlockMakeMasterObject:
PUBLIC
PROC [name: Rope.
ROPE]
RETURNS [mo: MasterObject] = {
mainBody: BlockRec ← BlockBody[];
lineBody: REF ANY ← PredefSweeps.GetUnitCube[];
shadeBody: REF ANY ← lineBody;
rayCastBody: REF ANY ← BlockGetRayCastBody[];
mo ← SVScene.CreateMasterObject[name, blockClass, mainBody, lineBody, shadeBody, rayCastBody];
};
BlockUpdate: PUBLIC PROC [mo: MasterObject, updateData: REF ANY] = {};
BlockBoundHedron:
PUBLIC
PROC [mo: MasterObject]
RETURNS [hedron: BoundHedron] = {
hedron ← SVBoundBox.RectangularBoundHedron[2, 2, 2];
};
BlockGetRayCastBody:
PROC []
RETURNS [surfaceArray: SurfaceArray] = {
upS, downS, frontS, backS, rightS, leftS: RectSurface;
surfaceArray ← NEW[SurfaceArrayObj];
upS ← NEW[RectSurfaceObj ← [up]];
downS ← NEW[RectSurfaceObj ← [down]];
frontS ← NEW[RectSurfaceObj ← [front]];
backS ← NEW[RectSurfaceObj ← [back]];
rightS ← NEW[RectSurfaceObj ← [right]];
leftS ← NEW[RectSurfaceObj ← [left]];
surfaceArray[1] ← upS;
surfaceArray[2] ← downS;
surfaceArray[3] ← frontS;
surfaceArray[4] ← backS;
surfaceArray[5] ← rightS;
surfaceArray[6] ← leftS;
}; -- end of BlockGetRayCastBody
BlockRayCast:
PUBLIC
PROC [cameraPoint: Point2d, localRay: Ray, masterObject:
REF
ANY, prim: Primitive]
RETURNS [class: Classification] = {
mo: MasterObject ← NARROW[masterObject];
RETURN[ObjectCast.BlockCast[localRay, NARROW[mo.rayCastBody], prim]];
};
BlockRayCastNoBBoxes:
PUBLIC
PROC [localRay: Ray, masterObject:
REF
ANY, prim: Primitive]
RETURNS [class: Classification] = {
mo: MasterObject ← NARROW[masterObject];
RETURN[ObjectCast.BlockCast[localRay, NARROW[mo.rayCastBody], prim]];
};
BlockRayCastBoundingSpheres:
PUBLIC
PROC [localRay: Ray, masterObject:
REF
ANY, prim: Primitive]
RETURNS [class: Classification] = {
mo: MasterObject ← NARROW[masterObject];
RETURN[ObjectCast.BlockCast[localRay, NARROW[mo.rayCastBody], prim]];
};
BlockLineDraw:
PUBLIC
PROC[dc: Imager.Context, data:
REF
ANY, camera: Camera, localCS: CoordSystem] = {
linMesh: LinearMesh;
IF ISTYPE[data, LinearMesh]
THEN linMesh ← NARROW[data]
ELSE SIGNAL WrongTypeOfData;
SweepGeometry.LineDrawLinearSweep[dc, linMesh, camera, localCS];
};
BlockDrawNormals:
PUBLIC
PROC[dc: Imager.Context, data:
REF
ANY, camera: Camera, localCS: CoordSystem] = {
linMesh: LinearMesh;
IF ISTYPE[data, LinearMesh]
THEN linMesh ← NARROW[data]
ELSE SIGNAL WrongTypeOfData;
SweepGeometry.DrawNormalsLinearSweep[dc, linMesh, camera, localCS];
};
BlockCountSurf:
PUBLIC
PROC [masterObject: MasterObject]
RETURNS [len:
NAT] = {
linMesh: LinearMesh ← NARROW[masterObject.shadeBody];
len ← SweepGeometry.CountPlanarSurfacesLinearSweep[linMesh];
};
BlockCountVert:
PUBLIC
PROC [masterObject: MasterObject]
RETURNS [len:
NAT] = {
linMesh: LinearMesh ← NARROW[masterObject.shadeBody];
len ← SweepGeometry.CountVerticesLinearSweep[linMesh];
};
BlockGetSurf:
PUBLIC
PROC [assembly: Assembly, camera: CoordSystem]
RETURNS [psl: PlanarSurfaceList] = {
shape: Shape ← NARROW[assembly.shape];
masterObject: MasterObject ← shape.mo;
linMesh: LinearMesh ← NARROW[masterObject.shadeBody];
psl ← SweepGeometry.PlanarSurfacesLinearSweep[linMesh, assembly, camera];
};
BlockDrawSurf:
PUBLIC
PROC [dc: Imager.Context, ps: PlanarSurface, lightSources: LightSourceList, camera: Camera] = {
SweepGeometry.DrawPlanarSurfaceLinearSweep[dc, ps, lightSources, camera];
};
BlockFilein:
PUBLIC
PROC [f:
IO.
STREAM, name: Rope.
ROPE]
RETURNS [mo: MasterObject] = {
TFI3d.ReadRope[f, "data: procedural"];
TFI3d.ReadBlank[f];
mo ← BlockMakeMasterObject[name];
};
BlockFileout:
PUBLIC
PROC [f:
IO.
STREAM, mo: MasterObject] = {
Blocks can be recovered from scratch.
f.PutF["data: procedural\n"];
};
BlockFileoutPoly:
PUBLIC
PROC [f:
IO.
STREAM, mo: MasterObject] = {
linMesh: LinearMesh ← NARROW[mo.shadeBody];
SweepGeometry.PolyListLinear[f, linMesh];
};
CylinderBody:
PROC
RETURNS [cylinderRec: CylinderRec] = {
cylinderRec ← NEW[CylinderRecObj];
cylinderRec.radius ← 1; cylinderRec.height ← 2;
};
CylinderMakeMasterObject:
PUBLIC
PROC [name: Rope.
ROPE]
RETURNS [mo: MasterObject] = {
mainBody: CylinderRec ← CylinderBody[];
lineBody: REF ANY ← PredefSweeps.GetUnitCylinder[];
shadeBody: REF ANY ← lineBody;
rayCastBody: REF ANY ← CylinderGetRayCastBody[];
mo ← SVScene.CreateMasterObject[name, cylinderClass, mainBody, lineBody, shadeBody, rayCastBody];
};
CylinderUpdate:
PUBLIC
PROC [mo: MasterObject, updateData:
REF
ANY] = {
mo.lineBody ← PredefSweeps.GetUnitCylinder[];
mo.shadeBody ← mo.lineBody;
mo.rayCastBody ← CylinderGetRayCastBody[];
};
CylinderBoundHedron:
PUBLIC
PROC [mo: MasterObject]
RETURNS [hedron: BoundHedron] = {
hedron ← SVBoundBox.HexagonalBoundHedron[1,1];
};
CylinderGetRayCastBody:
PROC []
RETURNS [surfaceArray: SurfaceArray] = {
topS, bottomS: DiskSurface;
tubeS: TubeSurface;
surfaceArray ← NEW[SurfaceArrayObj];
topS ← NEW[DiskSurfaceObj ← [top]];
bottomS ← NEW[DiskSurfaceObj ← [bottom]];
tubeS ← NEW[TubeSurfaceObj];
surfaceArray[1] ← topS;
surfaceArray[2] ← bottomS;
surfaceArray[3] ← tubeS;
}; -- end of CylinderGetRayCastBody
CylinderRayCast:
PUBLIC
PROC [cameraPoint: Point2d, localRay: Ray, masterObject:
REF
ANY, prim: Primitive]
RETURNS [class: Classification] = {
mo: MasterObject ← NARROW[masterObject];
RETURN[ObjectCast.CylinderCast[localRay, NARROW[mo.rayCastBody], prim]];
};
CylinderRayCastNoBBoxes:
PUBLIC
PROC [localRay: Ray, masterObject:
REF
ANY, prim: Primitive]
RETURNS [class: Classification] = {
mo: MasterObject ← NARROW[masterObject];
RETURN[ObjectCast.CylinderCast[localRay, NARROW[mo.rayCastBody], prim]];
};
CylinderRayCastBoundingSpheres:
PUBLIC
PROC [localRay: Ray, masterObject:
REF
ANY, prim: Primitive]
RETURNS [class: Classification] = {
mo: MasterObject ← NARROW[masterObject];
RETURN[ObjectCast.CylinderCast[localRay, NARROW[mo.rayCastBody], prim]];
};
CylinderLineDraw:
PUBLIC
PROC[dc: Imager.Context, data:
REF
ANY, camera: Camera, localCS: CoordSystem] = {
revMesh: RevoluteMesh;
IF ISTYPE[data, RevoluteMesh]
THEN revMesh ← NARROW[data]
ELSE SIGNAL WrongTypeOfData;
SweepGeometry.LineDrawRevoluteSweep[dc, revMesh, camera, localCS];
};
CylinderDrawNormals:
PUBLIC
PROC[dc: Imager.Context, data:
REF
ANY, camera: Camera, localCS: CoordSystem] = {
revMesh: RevoluteMesh;
IF ISTYPE[data, RevoluteMesh]
THEN revMesh ← NARROW[data]
ELSE SIGNAL WrongTypeOfData;
SweepGeometry.DrawNormalsRevoluteSweep[dc, revMesh, camera, localCS];
};
CylinderCountSurf:
PUBLIC
PROC [masterObject: MasterObject]
RETURNS [len:
NAT] = {
revMesh: RevoluteMesh ← NARROW[masterObject.shadeBody];
len ← SweepGeometry.CountPlanarSurfacesRevoluteSweep[revMesh];
};
CylinderCountVert:
PUBLIC
PROC [masterObject: MasterObject]
RETURNS [len:
NAT] = {
revMesh: RevoluteMesh ← NARROW[masterObject.shadeBody];
len ← SweepGeometry.CountVerticesRevoluteSweep[revMesh];
};
CylinderGetSurf:
PUBLIC
PROC [assembly: Assembly, camera: CoordSystem]
RETURNS [psl: PlanarSurfaceList] = {
shape: Shape ← NARROW[assembly.shape];
masterObject: MasterObject ← shape.mo;
revMesh: RevoluteMesh ← NARROW[masterObject.shadeBody];
psl ← SweepGeometry.PlanarSurfacesRevoluteSweep[revMesh, assembly, camera];
};
CylinderDrawSurf:
PUBLIC
PROC [dc: Imager.Context, ps: PlanarSurface, lightSources: LightSourceList, camera: Camera] = {
SweepGeometry.DrawPlanarSurfaceRevoluteSweep[dc, ps, lightSources, camera];
};
CylinderFilein:
PUBLIC
PROC [f:
IO.
STREAM, name: Rope.
ROPE]
RETURNS [mo: MasterObject] = {
TFI3d.ReadRope[f, "data: procedural"];
TFI3d.ReadBlank[f];
mo ← CylinderMakeMasterObject[name];
};
CylinderFileout:
PUBLIC
PROC [f:
IO.
STREAM, mo: MasterObject] = {
Cylinder can be recovered from scratch.
f.PutF["data: procedural\n"];
};
CylinderFileoutPoly:
PUBLIC
PROC [f:
IO.
STREAM, mo: MasterObject] = {
revMesh: RevoluteMesh ← NARROW[mo.shadeBody];
SweepGeometry.PolyListRevolute[f, revMesh];
};
ConeBody:
PROC
RETURNS [coneRec: ConeRec] = {
coneRec ← NEW[ConeRecObj];
coneRec.radius ← 1; coneRec.height ← 1;
};
ConeMakeMasterObject:
PUBLIC
PROC [name: Rope.
ROPE]
RETURNS [mo: MasterObject] = {
mainBody: ConeRec ← ConeBody[];
lineBody: REF ANY ← PredefSweeps.GetUnitCone[];
shadeBody: REF ANY ← lineBody;
rayCastBody: REF ANY ← ConeGetRayCastBody[];
mo ← SVScene.CreateMasterObject[name, coneClass, mainBody, lineBody, shadeBody, rayCastBody];
};
ConeUpdate:
PUBLIC
PROC [mo: MasterObject, updateData:
REF
ANY] = {
mo.lineBody ← PredefSweeps.GetUnitCone[];
mo.shadeBody ← mo.lineBody;
mo.rayCastBody ← ConeGetRayCastBody[];
};
ConeBoundHedron:
PUBLIC
PROC [mo: MasterObject]
RETURNS [hedron: BoundHedron] = {
hedron ← SVBoundBox.HexPyramidBoundHedron[1,1];
};
ConeGetRayCastBody:
PROC []
RETURNS [surfaceArray: SurfaceArray] = {
coneS: ConeSurface;
diskS: DiskSurface;
surfaceArray ← NEW[SurfaceArrayObj];
coneS ← NEW[ConeSurfaceObj];
diskS ← NEW[DiskSurfaceObj];
surfaceArray[1] ← coneS;
surfaceArray[2] ← diskS;
}; -- end of ConeGetRayCastBody
ConeRayCast:
PUBLIC
PROC [cameraPoint: Point2d, localRay: Ray, masterObject:
REF
ANY, prim: Primitive]
RETURNS [class: Classification] = {
mo: MasterObject ← NARROW[masterObject];
RETURN[ObjectCast.ConeCast[localRay, NARROW[mo.rayCastBody], prim]];};
ConeRayCastNoBBoxes:
PUBLIC
PROC [localRay: Ray, masterObject:
REF
ANY, prim: Primitive]
RETURNS [class: Classification] = {
mo: MasterObject ← NARROW[masterObject];
RETURN[ObjectCast.ConeCast[localRay, NARROW[mo.rayCastBody], prim]];};
ConeRayCastBoundingSpheres:
PUBLIC
PROC [localRay: Ray, masterObject:
REF
ANY, prim: Primitive]
RETURNS [class: Classification] = {
mo: MasterObject ← NARROW[masterObject];
RETURN[ObjectCast.ConeCast[localRay, NARROW[mo.rayCastBody], prim]];};
ConeLineDraw:
PUBLIC
PROC[dc: Imager.Context, data:
REF
ANY, camera: Camera, localCS: CoordSystem] = {
revMesh: RevoluteMesh;
IF ISTYPE[data, RevoluteMesh]
THEN revMesh ← NARROW[data]
ELSE SIGNAL WrongTypeOfData;
SweepGeometry.LineDrawRevoluteSweep[dc, revMesh, camera, localCS];
};
ConeDrawNormals:
PUBLIC
PROC[dc: Imager.Context, data:
REF
ANY, camera: Camera, localCS: CoordSystem] = {
revMesh: RevoluteMesh;
IF ISTYPE[data, RevoluteMesh]
THEN revMesh ← NARROW[data]
ELSE SIGNAL WrongTypeOfData;
SweepGeometry.DrawNormalsRevoluteSweep[dc, revMesh, camera, localCS];
};
ConeCountSurf:
PUBLIC
PROC [masterObject: MasterObject]
RETURNS [len:
NAT] = {
revMesh: RevoluteMesh ← NARROW[masterObject.shadeBody];
len ← SweepGeometry.CountPlanarSurfacesRevoluteSweep[revMesh];
};
ConeCountVert:
PUBLIC
PROC [masterObject: MasterObject]
RETURNS [len:
NAT] = {
revMesh: RevoluteMesh ← NARROW[masterObject.shadeBody];
len ← SweepGeometry.CountVerticesRevoluteSweep[revMesh];
};
ConeGetSurf:
PUBLIC
PROC [assembly: Assembly, camera: CoordSystem]
RETURNS [psl: PlanarSurfaceList] = {
shape: Shape ← NARROW[assembly.shape];
masterObject: MasterObject ← shape.mo;
revMesh: RevoluteMesh ← NARROW[masterObject.shadeBody];
psl ← SweepGeometry.PlanarSurfacesRevoluteSweep[revMesh, assembly, camera];
};
ConeDrawSurf:
PUBLIC
PROC [dc: Imager.Context, ps: PlanarSurface, lightSources: LightSourceList, camera: Camera] = {
SweepGeometry.DrawPlanarSurfaceRevoluteSweep[dc, ps, lightSources, camera];
};
ConeFilein:
PUBLIC
PROC [f:
IO.
STREAM, name: Rope.
ROPE]
RETURNS [mo: MasterObject] = {
TFI3d.ReadRope[f, "data: procedural"];
TFI3d.ReadBlank[f];
mo ← ConeMakeMasterObject[name];
};
ConeFileout:
PUBLIC
PROC [f:
IO.
STREAM, mo: MasterObject] = {
Cone can be recovered from scratch.
f.PutF["data: procedural\n"];
};
ConeFileoutPoly:
PUBLIC
PROC [f:
IO.
STREAM, mo: MasterObject] = {
revMesh: RevoluteMesh ← NARROW[mo.shadeBody];
SweepGeometry.PolyListRevolute[f, revMesh];
};
TorusBody:
PROC [bigRadius:
REAL, sectionRadius:
REAL]
RETURNS [torusRec: TorusRec] = {
torusRec ← NEW[TorusRecObj];
torusRec.bigRadius ← bigRadius;
torusRec.sectionRadius ← sectionRadius;
};
TorusMakeMasterObject:
PUBLIC
PROC [name: Rope.
ROPE, bigRadius:
REAL, sectionRadius:
REAL]
RETURNS [mo: MasterObject] = {
mainBody: TorusRec ← TorusBody[bigRadius, sectionRadius];
lineBody: REF ANY ← PredefSweeps.CreateTorus[mainBody.bigRadius, mainBody.sectionRadius];
shadeBody: REF ANY ← lineBody;
rayCastBody: REF ANY ← TorusGetRayCastBody[];
mo ← SVScene.CreateMasterObject[name, torusClass, mainBody, lineBody, shadeBody, rayCastBody];
};
TorusUpdate:
PUBLIC
PROC [mo: MasterObject, updateData:
REF
ANY] = {
mainBody: TorusRec ← NARROW[mo.mainBody];
mo.lineBody ← PredefSweeps.CreateTorus[mainBody.bigRadius, mainBody.sectionRadius];
mo.shadeBody ← mo.lineBody;
mo.rayCastBody ← TorusGetRayCastBody[];
};
TorusBoundHedron:
PUBLIC
PROC [mo: MasterObject]
RETURNS [hedron: BoundHedron] = {
torusRec: TorusRec ← NARROW[mo.mainBody];
hedron ←
SVBoundBox.HexagonalBoundHedron[torusRec.bigRadius + torusRec.sectionRadius,
torusRec.sectionRadius];
};
TorusGetRayCastBody:
PROC []
RETURNS [surfaceArray: SurfaceArray] = {
torusS: ToroidalSurface;
surfaceArray ← NEW[SurfaceArrayObj];
torusS ← NEW[ToroidalSurfaceObj];
surfaceArray[1] ← torusS;
}; -- end of TorusGetRayCastBody
TorusRayCast:
PUBLIC
PROC [cameraPoint: Point2d, localRay: Ray, masterObject:
REF
ANY, prim: Primitive]
RETURNS [class: Classification] = {
mo: MasterObject ← NARROW[masterObject];
surfaceArray: SurfaceArray ← NARROW[mo.rayCastBody];
RETURN[ObjectCast.ToroidCast[localRay, prim, mo.mainBody, surfaceArray[1]]];
};
TorusRayCastNoBBoxes:
PUBLIC
PROC [localRay: Ray, masterObject:
REF
ANY, prim: Primitive]
RETURNS [class: Classification] = {
mo: MasterObject ← NARROW[masterObject];
surfaceArray: SurfaceArray ← NARROW[mo.rayCastBody];
RETURN[ObjectCast.ToroidCast[localRay, prim, mo.mainBody, surfaceArray[1]]];
};
TorusRayCastBoundingSpheres:
PUBLIC
PROC [localRay: Ray, masterObject:
REF
ANY, prim: Primitive]
RETURNS [class: Classification] = {
mo: MasterObject ← NARROW[masterObject];
surfaceArray: SurfaceArray ← NARROW[mo.rayCastBody];
RETURN[ObjectCast.ToroidCast[localRay, prim, mo.mainBody, surfaceArray[1]]];
};
TorusLineDraw:
PUBLIC
PROC[dc: Imager.Context, data:
REF
ANY, camera: Camera, localCS: CoordSystem] = {
torMesh: ToroidalMesh;
IF ISTYPE[data, ToroidalMesh]
THEN torMesh ← NARROW[data]
ELSE SIGNAL WrongTypeOfData;
SweepGeometry.LineDrawToroidalSweep[dc, torMesh, camera, localCS];
};
TorusDrawNormals:
PUBLIC
PROC[dc: Imager.Context, data:
REF
ANY, camera: Camera, localCS: CoordSystem] = {
torMesh: ToroidalMesh;
IF ISTYPE[data, ToroidalMesh]
THEN torMesh ← NARROW[data]
ELSE SIGNAL WrongTypeOfData;
SweepGeometry.DrawNormalsToroidalSweep[dc, torMesh, camera, localCS];
};
TorusCountSurf:
PUBLIC
PROC [masterObject: MasterObject]
RETURNS [len:
NAT] = {
torMesh: ToroidalMesh ← NARROW[masterObject.shadeBody];
len ← SweepGeometry.CountPlanarSurfacesToroidalSweep[torMesh];
};
TorusCountVert:
PUBLIC
PROC [masterObject: MasterObject]
RETURNS [len:
NAT] = {
torMesh: ToroidalMesh ← NARROW[masterObject.shadeBody];
len ← SweepGeometry.CountVerticesToroidalSweep[torMesh];
};
TorusGetSurf:
PUBLIC
PROC [assembly: Assembly, camera: CoordSystem]
RETURNS [psl: PlanarSurfaceList] = {
shape: Shape ← NARROW[assembly.shape];
masterObject: MasterObject ← shape.mo;
torMesh: ToroidalMesh ← NARROW[masterObject.shadeBody];
psl ← SweepGeometry.PlanarSurfacesToroidalSweep[torMesh, assembly, camera];
};
TorusDrawSurf:
PUBLIC
PROC [dc: Imager.Context, ps: PlanarSurface, lightSources: LightSourceList, camera: Camera] = {
SweepGeometry.DrawPlanarSurfaceToroidalSweep[dc, ps, lightSources, camera];
};
TorusFilein:
PUBLIC
PROC [f:
IO.
STREAM, name: Rope.
ROPE]
RETURNS [mo: MasterObject] = {
bigRadius, sectionRadius: REAL;
TFI3d.ReadBlankAndRope[f, "bigRadius:"];
bigRadius ← TFI3d.ReadBlankAndReal[f];
TFI3d.ReadBlankAndRope[f, ","];
TFI3d.ReadBlankAndRope[f, "sectionRadius:"];
sectionRadius ← TFI3d.ReadBlankAndReal[f];
mo ← TorusMakeMasterObject[name, bigRadius, sectionRadius];
};
TorusFileout:
PUBLIC
PROC [f:
IO.
STREAM, mo: MasterObject] = {
Torus can be recovered from bigRadius and sectionRadius.
torusRec: TorusRec ← NARROW[mo.mainBody];
f.PutF["bigRadius: %g, sectionRadius: %g\n", [real[torusRec.bigRadius]],
[real[torusRec.sectionRadius]] ];
};-- end of TorusFileout
TorusFileoutPoly:
PUBLIC
PROC [f:
IO.
STREAM, mo: MasterObject] = {
torMesh: ToroidalMesh ← NARROW[mo.shadeBody];
SweepGeometry.PolyListToroidal[f, torMesh];
};
LinSweepMakeMasterObject:
PUBLIC
PROC [name: Rope.
ROPE, linMesh: LinearMesh]
RETURNS [mo: MasterObject] = {
mainBody: REF ANY ← NIL;
lineBody: REF ANY ← linMesh;
shadeBody: REF ANY ← lineBody;
rayCastBody: REF ANY ← LinSweepGetRayCastBody[linMesh];
mo ← SVScene.CreateMasterObject[name, linClass, mainBody, lineBody, shadeBody, rayCastBody];
};
LinSweepUpdate:
PUBLIC
PROC [mo: MasterObject, updateData:
REF
ANY] = {
};
LinSweepBoundHedron:
PUBLIC
PROC [masterObject: MasterObject]
RETURNS [hedron: BoundHedron] = {
linMesh: LinearMesh ← NARROW[masterObject.lineBody];
vertCount: NAT ← 2*linMesh.len;
hedron ← SVBoundBox.CreateBoundHedron[vertCount];
FOR i: NAT IN[1..linMesh.len] DO
FOR j: NAT IN[1..2] DO
SVBoundBox.AddBoundHedronPoint[hedron, linMesh.array[i][j]];
ENDLOOP;
ENDLOOP;
};
LinSweepFaces: TYPE = SweepCast.LinSweepFaces;
LinSweepHint: TYPE = REF LinSweepHintObj;
LinSweepHintObj: TYPE = RECORD [linMesh: LinearMesh, faces: LinSweepFaces];
LinSweepGetRayCastBody:
PROC [linMesh: LinearMesh]
RETURNS [hint: LinSweepHint] = {
hint ← NEW[LinSweepHintObj];
hint.linMesh ← linMesh;
hint.faces ← SweepCast.MakeLinSweepFaces[linMesh];
};
GetLinSweepData:
PUBLIC
PROC
RETURNS [linMesh: LinearMesh] = {
linMesh ← PredefSweeps.GetUnitCube[];-- for now.
};
LinSweepRayCast:
PUBLIC
PROC [cameraPoint: Point2d, localRay: Ray, masterObject:
REF
ANY, prim: Primitive]
RETURNS [class: Classification] = {
mo: MasterObject ← NARROW[masterObject];
rayCastBody: LinSweepHint ← NARROW[mo.rayCastBody];
class ← SweepCast.LinCast[localRay, prim, rayCastBody.linMesh, rayCastBody.faces];
};
LinSweepRayCastNoBBoxes:
PUBLIC
PROC [localRay: Ray, masterObject:
REF
ANY, prim: Primitive]
RETURNS [class: Classification] = {
mo: MasterObject ← NARROW[masterObject];
rayCastBody: LinSweepHint ← NARROW[mo.rayCastBody];
class ← SweepCast.LinCast[localRay, prim, rayCastBody.linMesh, rayCastBody.faces];
};
LinSweepRayCastBoundingSpheres:
PUBLIC
PROC [localRay: Ray, masterObject:
REF
ANY, prim: Primitive]
RETURNS [class: Classification] = {
mo: MasterObject ← NARROW[masterObject];
rayCastBody: LinSweepHint ← NARROW[mo.rayCastBody];
class ← SweepCast.LinCast[localRay, prim, rayCastBody.linMesh, rayCastBody.faces];
};
LinSweepLineDraw:
PUBLIC
PROC[dc: Imager.Context, data:
REF
ANY, camera: Camera, localCS: CoordSystem] = {
linMesh: LinearMesh;
IF ISTYPE[data, LinearMesh]
THEN linMesh ← NARROW[data]
ELSE SIGNAL WrongTypeOfData;
SweepGeometry.LineDrawLinearSweep[dc, linMesh, camera, localCS];
};
LinSweepDrawNormals:
PUBLIC
PROC[dc: Imager.Context, data:
REF
ANY, camera: Camera, localCS: CoordSystem] = {
linMesh: LinearMesh;
IF ISTYPE[data, LinearMesh]
THEN linMesh ← NARROW[data]
ELSE SIGNAL WrongTypeOfData;
SweepGeometry.DrawNormalsLinearSweep[dc, linMesh, camera, localCS];
};
LinSweepCountSurf:
PUBLIC
PROC [masterObject: MasterObject]
RETURNS [len:
NAT] = {
linMesh: LinearMesh ← NARROW[masterObject.shadeBody];
len ← SweepGeometry.CountPlanarSurfacesLinearSweep[linMesh];
};
LinSweepCountVert:
PUBLIC
PROC [masterObject: MasterObject]
RETURNS [len:
NAT] = {
linMesh: LinearMesh ← NARROW[masterObject.shadeBody];
len ← SweepGeometry.CountVerticesLinearSweep[linMesh];
};
LinSweepGetSurf:
PUBLIC
PROC [assembly: Assembly, camera: CoordSystem]
RETURNS [psl: PlanarSurfaceList] = {
shape: Shape ← NARROW[assembly.shape];
masterObject: MasterObject ← shape.mo;
linMesh: LinearMesh ← NARROW[masterObject.shadeBody];
psl ← SweepGeometry.PlanarSurfacesLinearSweep[linMesh, assembly, camera];
};
LinSweepDrawSurf:
PUBLIC
PROC [dc: Imager.Context, ps: PlanarSurface, lightSources: LightSourceList, camera: Camera] = {
SweepGeometry.DrawPlanarSurfaceLinearSweep[dc, ps, lightSources, camera];
};
LinearFileout:
PUBLIC
PROC [f:
IO.
STREAM, mo: MasterObject] = {
linMesh: LinearMesh ← NARROW[mo.lineBody];
lma: LinearMeshArray ← linMesh.array;
len: NAT ← linMesh.len;
f.PutF["name: %g\n",[rope[mo.name]]];
Assume that the defining contour has not been rotated. Output elements [i][1]
f.PutF["frontDepth: %g, backDepth: %g\n",[real[lma[1][1][3]]],[real[lma[1][2][3]]]];
f.PutF["DataPoints [%g]: ",[integer[len]]];
FOR i: NAT IN[1..len-1] DO
TFO3d.FileoutPoint3dAsPoint2d[f, lma[i][1]];
f.PutF[","];
ENDLOOP;
TFO3d.FileoutPoint3dAsPoint2d[f, lma[len][1]];
f.PutChar[IO.CR];
};
LinearFilein:
PUBLIC
PROC [f:
IO.
STREAM, name: Rope.
ROPE]
RETURNS [mo: MasterObject] = {
count: NAT;
frontDepth, backDepth: REAL;
poly: Polygon;
instanceName: Rope.ROPE;
linMesh: LinearMesh;
TFI3d.ReadRope[f, "name:"];
instanceName ← TFI3d.ReadBlankAndWord[f];
TFI3d.ReadBlankAndRope[f, "frontDepth:"];
frontDepth ← TFI3d.ReadBlankAndReal[f];
TFI3d.ReadBlankAndRope[f, ","];
TFI3d.ReadBlankAndRope[f, "backDepth:"];
backDepth ← TFI3d.ReadBlankAndReal[f];
TFI3d.ReadBlankAndRope[f, "DataPoints ["];
count ← TFI3d.ReadNAT[f];
TFI3d.ReadBlankAndRope[f, "]:"];
TFI3d.ReadBlank[f];
poly ← SVPolygon2d.CreatePoly[count];
FOR i:
NAT
IN[1..count-1]
DO
poly ← SVPolygon2d.PutPolyPoint[poly, i-1, TFI3d.ReadPoint2d[f]];
TFI3d.ReadBlankAndRope[f, ","];
TFI3d.ReadBlank[f];
ENDLOOP;
poly ← SVPolygon2d.PutPolyPoint[poly, count-1, TFI3d.ReadPoint2d[f]];
TFI3d.ReadBlank[f];
linMesh ← SweepGeometry.LinearSweep[poly, frontDepth, backDepth];
mo ← LinSweepMakeMasterObject[name, linMesh];
};
LinearFileoutPoly:
PUBLIC
PROC [f:
IO.
STREAM, mo: MasterObject] = {
linMesh: LinearMesh ← NARROW[mo.shadeBody];
SweepGeometry.PolyListLinear[f, linMesh];
};
RevoSweepMakeMasterObject:
PUBLIC
PROC [name: Rope.
ROPE, path: Path, long:
NAT]
RETURNS [mo: MasterObject] = {
mainBody: RevoSweepRec ← NEW[RevoSweepRecObj ← [path: path]];
lineBody: REF ANY;
shadeBody: REF ANY;
rayCastBody: REF ANY;
revMesh: RevoluteMesh;
revMesh ← SweepGeometry.RevoluteSweep[path, long];
lineBody ← revMesh;
shadeBody ← lineBody;
rayCastBody ← RevoSweepGetRayCastBody[revMesh];
mo ← SVScene.CreateMasterObject[name, revoClass, mainBody, lineBody, shadeBody, rayCastBody];
};
RevoSweepUpdate:
PUBLIC
PROC [mo: MasterObject, updateData:
REF
ANY] = {
revMesh: RevoluteMesh;
mainBody: RevoSweepRec ← NARROW[mo.mainBody];
path: Path ← mainBody.path;
revMesh ← SweepGeometry.RevoluteSweep[path, PredefSweeps.GetLinesOfLongitude[]];
mo.lineBody ← revMesh;
mo.shadeBody ← mo.lineBody;
mo.rayCastBody ← RevoSweepGetRayCastBody[revMesh];
};
RevoSweepBoundHedron:
PUBLIC
PROC [masterObject: MasterObject]
RETURNS [hedron: BoundHedron] = {
revMesh: RevoluteMesh ← NARROW[masterObject.shadeBody];
vertCount: NAT ← revMesh.linesOfLatitude*6;-- hexagons*6
hex: Poly3d;
hedron ← SVBoundBox.CreateBoundHedron[vertCount];
FOR i: NAT IN[1..revMesh.linesOfLatitude] DO
the radius at this line of latitude is revMesh.array[i][revMesh.linesOfLongitude][1];
hex ← SVPolygon3d.CircumHexagon[revMesh.array[i][1][2],
revMesh.array[i][revMesh.linesOfLongitude][1]];
SVBoundBox.AddBoundHedronPoly[hedron, hex];
ENDLOOP;
};
RevoSweepHint: TYPE = REF RevoSweepHintObj;
RevoSweepHintObj:
TYPE =
RECORD [
boxes: SubBoxesBody,
spheres: SubSpheresBody];
RevoSweepFaces: TYPE = SweepCast.RevoSweepFaces;
RevoSweepRayCastBody: TYPE = REF RevoSweepRayCastBodyObj;
RevoSweepRayCastBodyObj: TYPE = RECORD [faces: RevoSweepFaces];
RevoSweepGetRayCastBody:
PROC [revMesh: RevoluteMesh]
RETURNS [rayCastBody: RevoSweepRayCastBody] = {
rayCastBody ← NEW[RevoSweepRayCastBodyObj];
rayCastBody.faces ← SweepCast.MakeRevoSweepFaces[revMesh];
};
RevoSweepRayCast:
PUBLIC
PROC [cameraPoint: Point2d, localRay: Ray, masterObject:
REF
ANY, prim: Primitive]
RETURNS [class: Classification] = {
mo: MasterObject ← NARROW[masterObject];
rayCastBody: RevoSweepRayCastBody ← NARROW[mo.rayCastBody];
revoHint: RevoSweepHint ← NARROW[prim.hints];
RETURN[SweepCast.RevoCast[cameraPoint, localRay, prim, rayCastBody.faces, revoHint.boxes]];
prim.hints is a set of bounding boxes
};
RevoSweepRayCastNoBBoxes:
PUBLIC
PROC [localRay: Ray, masterObject:
REF
ANY, prim: Primitive]
RETURNS [class: Classification] = {
mo: MasterObject ← NARROW[masterObject];
rayCastBody: RevoSweepRayCastBody ← NARROW[mo.rayCastBody];
RETURN[SweepCast.RevoCastNoBBoxes[localRay, prim, rayCastBody.faces]];
};
RevoSweepRayCastBoundingSpheres:
PUBLIC
PROC [localRay: Ray, masterObject:
REF
ANY, prim: Primitive]
RETURNS [class: Classification] = {
mo: MasterObject ← NARROW[masterObject];
rayCastBody: RevoSweepRayCastBody ← NARROW[mo.rayCastBody];
revoHint: RevoSweepHint ← NARROW[prim.hints];
RETURN[SweepCast.RevoCastBoundSpheres[localRay, prim, rayCastBody.faces, revoHint.spheres]];
};
RevoSweepPreprocess:
PUBLIC
PROC [prim: Primitive, camera: Camera] = {
revoSweepHint: RevoSweepHint ← NEW[RevoSweepHintObj];
mo: MasterObject ← NARROW[prim.mo];
rayCastBody: RevoSweepRayCastBody ← NARROW[mo.rayCastBody];
faces: RevoSweepFaces ← rayCastBody.faces;
boxes: SubBoxesBody;
spheres: SubSpheresBody;
worldCS: CoordSystem ← camera.coordSys.parent;
revoSweepHint.boxes ← NEW[SubBoxesBodyObj[faces.len]];
revoSweepHint.spheres ← NEW[SubSpheresBodyObj[faces.len]];
boxes ← revoSweepHint.boxes;
spheres ← revoSweepHint.spheres;
FOR i:
NAT
IN[0..faces.len)
DO
WITH faces[i]
SELECT
FROM
cone: Cone => {
boxes[i] ← SVBoundBox.BoundBoxFromBoundHedron[cone.boundHedron, camera, prim.primWRTAssembly];
spheres[i] ← SVBoundSphere.BoundSphereFromBoundHedron[cone.boundHedron, worldCS, prim.primWRTAssembly];
};
ring: DiskRing=> {
boxes[i] ← SVBoundBox.BoundBoxFromBoundHedron[ring.boundHedron, camera, prim.primWRTAssembly];
spheres[i] ← SVBoundSphere.BoundSphereFromBoundHedron[ring.boundHedron, worldCS, prim.primWRTAssembly];
};
cyl: Cylinder=> {
boxes[i] ← SVBoundBox.BoundBoxFromBoundHedron[cyl.boundHedron, camera, prim.primWRTAssembly];
spheres[i] ← SVBoundSphere.BoundSphereFromBoundHedron[cyl.boundHedron, worldCS, prim.primWRTAssembly];
};
ENDCASE => ERROR;
ENDLOOP;
spheres.len ← faces.len;
boxes.len ← faces.len;
prim.hints ← revoSweepHint;
};
RevoSweepLineDraw:
PUBLIC
PROC[dc: Imager.Context, data:
REF
ANY, camera: Camera, localCS: CoordSystem] = {
revMesh: RevoluteMesh;
IF ISTYPE[data, RevoluteMesh]
THEN revMesh ← NARROW[data]
ELSE SIGNAL WrongTypeOfData;
SweepGeometry.LineDrawRevoluteSweep[dc, revMesh, camera, localCS];
};
RevoSweepDrawNormals:
PUBLIC
PROC[dc: Imager.Context, data:
REF
ANY, camera: Camera, localCS: CoordSystem] = {
revMesh: RevoluteMesh;
IF ISTYPE[data, RevoluteMesh]
THEN revMesh ← NARROW[data]
ELSE SIGNAL WrongTypeOfData;
SweepGeometry.DrawNormalsRevoluteSweep[dc, revMesh, camera, localCS];
};
RevoSweepCountSurf:
PUBLIC
PROC [masterObject: MasterObject]
RETURNS [len:
NAT] = {
revMesh: RevoluteMesh ← NARROW[masterObject.shadeBody];
len ← SweepGeometry.CountPlanarSurfacesRevoluteSweep[revMesh];
};
RevoSweepCountVert:
PUBLIC
PROC [masterObject: MasterObject]
RETURNS [len:
NAT] = {
revMesh: RevoluteMesh ← NARROW[masterObject.shadeBody];
len ← SweepGeometry.CountVerticesRevoluteSweep[revMesh];
};
RevoSweepGetSurf:
PUBLIC
PROC [assembly: Assembly, camera: CoordSystem]
RETURNS [psl: PlanarSurfaceList] = {
shape: Shape ← NARROW[assembly.shape];
masterObject: MasterObject ← shape.mo;
revMesh: RevoluteMesh ← NARROW[masterObject.shadeBody];
psl ← SweepGeometry.PlanarSurfacesRevoluteSweep[revMesh, assembly, camera];
};
RevoSweepDrawSurf:
PUBLIC
PROC [dc: Imager.Context, ps: PlanarSurface, lightSources: LightSourceList, camera: Camera] = {
SweepGeometry.DrawPlanarSurfaceRevoluteSweep[dc, ps, lightSources, camera];
};
RevoSweepDrawSubBoxes:
PUBLIC
PROC [dc: Imager.Context, prim: Primitive, screenCS: CoordSystem] = {
revoHint: RevoSweepHint ← NARROW[prim.hints];
boxes: SubBoxesBody ← revoHint.boxes;
FOR i:
NAT
IN [0..boxes.len)
DO
SVBoundBox.DrawBoundBox[dc, boxes[i], screenCS];
ENDLOOP;
};
RevoSweepDrawSubSpheres:
PUBLIC
PROC [dc: Imager.Context, prim: Primitive, camera: Camera] = {
revoHint: RevoSweepHint ← NARROW[prim.hints];
spheres: SubSpheresBody ← revoHint.spheres;
FOR i:
NAT
IN [0..spheres.len)
DO
SVBoundSphere.DrawBoundSphere[dc, spheres[i], camera];
ENDLOOP;
};
RevoluteFileout:
PUBLIC
PROC [f:
IO.
STREAM, mo: MasterObject] = {
rma: RevoluteMeshArray;
revMesh: RevoluteMesh ← NARROW[mo.lineBody];
lat, long: NAT;
rma ← revMesh.array;
lat ← revMesh.linesOfLatitude;
long ← revMesh.linesOfLongitude;
assume that the defining contour has not been rotated. Output the [i][long] points
f.PutF["lat: %g, long: %g\npoints [%g]:\n", -- TAB
[integer[lat]],[integer[long]],[integer[lat]]];
FOR i: NAT IN[1..lat-1] DO
TFO3d.FileoutPoint3dAsPoint2d[f, rma[i][long]];
f.PutF[","];
IF (i/3)*3 = i THEN f.PutF["\n"]; -- CR TAB
ENDLOOP;
TFO3d.FileoutPoint3dAsPoint2d[f, rma[lat][long]];
f.PutChar[IO.CR];
};
RevoluteFilein:
PUBLIC
PROC [f:
IO.
STREAM, name: Rope.
ROPE]
RETURNS [mo: MasterObject] = {
lat, long, count: NAT;
path: Path;
TFI3d.ReadBlankAndRope[f, "lat:"];
lat ← TFI3d.ReadBlankAndNAT[f];
TFI3d.ReadBlankAndRope[f, ","];
TFI3d.ReadBlankAndRope[f, "long:"];
long ← TFI3d.ReadBlankAndNAT[f];
TFI3d.ReadBlankAndRope[f, "points"];
TFI3d.ReadBlankAndRope[f, "["];
count ← TFI3d.ReadBlankAndNAT[f];
TFI3d.ReadBlankAndRope[f, "]:"];
TFI3d.ReadBlank[f];
path ← SVPolygon2d.CreatePath[count];
FOR i:
NAT
IN[1..count-1]
DO
SVPolygon2d.PutPathPoint[path, i-1, TFI3d.ReadPoint2d[f]];
TFI3d.ReadBlankAndRope[f, ","];
TFI3d.ReadBlank[f];
ENDLOOP;
SVPolygon2d.PutPathPoint[path, lat-1, TFI3d.ReadPoint2d[f]];
TFI3d.ReadBlank[f];
mo ← RevoSweepMakeMasterObject[name, path, long];
};
RevoluteFileoutPoly:
PUBLIC
PROC [f:
IO.
STREAM, mo: MasterObject] = {
revMesh: RevoluteMesh ← NARROW[mo.shadeBody];
SweepGeometry.PolyListRevolute[f, revMesh];
};
Init:
PROC = {
sphere, block, cylinder, cone: MasterObject;
sphereClass ← SVScene.RegisterMasterObjectClass[
"sphere",
SphereUpdate,
SphereFilein,
SphereFileout,
SphereFileoutPoly,
SphereRayCast,
SphereRayCastNoBBoxes,
SphereRayCastBoundingSpheres,
SphereBoundHedron,
SVScene.NoOpPreprocess,
SphereLineDraw,
SphereDrawNormals,
SphereCountSurf,
SphereGetSurf,
SphereDrawSurf,
SVScene.NoOpDrawSubBoxes,
SVScene.NoOpDrawSubSpheres];
blockClass ← SVScene.RegisterMasterObjectClass[
"block",
BlockUpdate,
BlockFilein,
BlockFileout,
BlockFileoutPoly,
BlockRayCast,
BlockRayCastNoBBoxes,
BlockRayCastBoundingSpheres,
BlockBoundHedron,
SVScene.NoOpPreprocess,
BlockLineDraw,
BlockDrawNormals,
BlockCountSurf,
BlockGetSurf,
BlockDrawSurf,
SVScene.NoOpDrawSubBoxes,
SVScene.NoOpDrawSubSpheres];
cylinderClass ← SVScene.RegisterMasterObjectClass[
"cylinder",
CylinderUpdate,
CylinderFilein,
CylinderFileout,
CylinderFileoutPoly,
CylinderRayCast,
CylinderRayCastNoBBoxes,
CylinderRayCastBoundingSpheres,
CylinderBoundHedron,
SVScene.NoOpPreprocess,
CylinderLineDraw,
CylinderDrawNormals,
CylinderCountSurf,
CylinderGetSurf,
CylinderDrawSurf,
SVScene.NoOpDrawSubBoxes,
SVScene.NoOpDrawSubSpheres];
coneClass ← SVScene.RegisterMasterObjectClass[
"cone",
ConeUpdate,
ConeFilein,
ConeFileout,
ConeFileoutPoly,
ConeRayCast,
ConeRayCastNoBBoxes,
ConeRayCastBoundingSpheres,
ConeBoundHedron,
SVScene.NoOpPreprocess,
ConeLineDraw,
ConeDrawNormals,
ConeCountSurf,
ConeGetSurf,
ConeDrawSurf,
SVScene.NoOpDrawSubBoxes,
SVScene.NoOpDrawSubSpheres];
torusClass ← SVScene.RegisterMasterObjectClass[
"torus",
TorusUpdate,
TorusFilein,
TorusFileout,
TorusFileoutPoly,
TorusRayCast,
TorusRayCastNoBBoxes,
TorusRayCastBoundingSpheres,
TorusBoundHedron,
SVScene.NoOpPreprocess,
TorusLineDraw,
TorusDrawNormals,
TorusCountSurf,
TorusGetSurf,
TorusDrawSurf,
SVScene.NoOpDrawSubBoxes,
SVScene.NoOpDrawSubSpheres];
linClass ← SVScene.RegisterMasterObjectClass[
"linearSweep",
LinSweepUpdate,
LinearFilein,
LinearFileout,
LinearFileoutPoly,
LinSweepRayCast,
LinSweepRayCastNoBBoxes,
LinSweepRayCastBoundingSpheres,
LinSweepBoundHedron,
SVScene.NoOpPreprocess,
LinSweepLineDraw,
LinSweepDrawNormals,
LinSweepCountSurf,
LinSweepGetSurf,
LinSweepDrawSurf,
SVScene.NoOpDrawSubBoxes,
SVScene.NoOpDrawSubSpheres];
revoClass ← SVScene.RegisterMasterObjectClass[
"revoluteSweep",
RevoSweepUpdate,
RevoluteFilein,
RevoluteFileout,
RevoluteFileoutPoly,
RevoSweepRayCast,
RevoSweepRayCastNoBBoxes,
RevoSweepRayCastBoundingSpheres,
RevoSweepBoundHedron,
RevoSweepPreprocess,
RevoSweepLineDraw,
RevoSweepDrawNormals,
RevoSweepCountSurf,
RevoSweepGetSurf,
RevoSweepDrawSurf,
RevoSweepDrawSubBoxes,
RevoSweepDrawSubSpheres];
sphere ← SphereMakeMasterObject["sphere"];
block ← BlockMakeMasterObject["block"];
cylinder ← CylinderMakeMasterObject["cylinder"];
cone ← ConeMakeMasterObject["cone"];
SVScene.RegisterMasterObject[sphere];
SVScene.RegisterMasterObject[block];
SVScene.RegisterMasterObject[cylinder];
SVScene.RegisterMasterObject[cone];
};
Init[];
END.