File: CSGImpl.mesa
Last edited by Bier on July 5, 1983 5:01 pm
Contents: The csg Solids Interface. Essentially maintains a database of csg trees each of which contains one or more combined primitives. Maintaining a tree involves creating primitives and adding them to trees with the csg operations, intersection, union, and difference.
DIRECTORY
CSG,
GraphicsColor,
Rope,
SVBoundBox;
CSGImpl: PROGRAM
IMPORTS SVBoundBox
EXPORTS CSG =
BEGIN
BoundBox: TYPE = REF BoundBoxObj;
BoundBoxObj: TYPE = SVBoundBox.BoundBoxObj;
Classification: TYPE = REF ClassificationObj;
ClassificationObj: TYPE = CSG.ClassificationObj;
Color: TYPE = GraphicsColor.Color;
Primitive: TYPE = REF PrimitiveObj;
PrimitiveObj: TYPE = CSG.PrimitiveObj;
PointSetOp: TYPE = CSG.PointSetOp;-- {union, intersection, difference};
Composite: TYPE = REF CompositeObj;
CompositeObj: TYPE = CSG.CompositeObj;
CSGTree: TYPE = REF CSGTreeObj;
CSGTreeObj: TYPE = CSG.CSGTreeObj;
In my current plan, all of the instances of each surface type will refer to the same underlying csg surface expressed in the instance (unit dimensions) coordinate system. Hence, I will build these primitve shapes into the code (this more or less must be done anyway because the formulas - x^2 + y^2 = R^2; z = constant, etc. - are hard to enter symbolically in Mesa).
However, for rapid rendering, I will have a line-drawing approximation to each world surface. These will involve a sweep-based representation with a finite mesh (translational sweep for blocks, rotational for cylinders and spheres). I will create one such representation for each of the primitive solid types in the same instance coordinate system in which the exact csg reps are defined. Rendering line-drawings with the sweep reps will then involve, using the same matrix transforms as are used to place the csg shapes, followed by a perspective transform and a call to 2d graphics routines.
CopyClass: PUBLIC PROC [class: Classification] RETURNS [copy: Classification] = {
copy ← NEW[ClassificationObj];
copy.count ← class.count;
copy.params ← class.params;
copy.surfaces ← class.surfaces;
copy.primitives ← class.primitives;
copy.classifs ← class.classifs;
copy.normals ← class.normals;
};
MakeCompositeCell: PUBLIC PROC [name: Rope.ROPE, operation: PointSetOp, LeftSolidPtr: REF ANY, RightSolidPtr: REF ANY] RETURNS [c: Composite] = {
c ← NEW[CompositeObj ← [name, operation, LeftSolidPtr, RightSolidPtr]];
};
MakeCSGTree: PUBLIC PROC [son: REF ANY, backgroundColor: Color, shadows: BOOL] RETURNS [tree: CSGTree] = {
name: Rope.ROPE;
IF son = NIL THEN name ← "Empty Scene"
ELSE {
WITH son SELECT FROM
prim: Primitive => name ← prim.name;
comp: Composite => name ← comp.name;
ENDCASE => ERROR;
};
tree ← NEW[CSGTreeObj ← [name, son, backgroundColor, shadows]];
};
CombineBoundBoxes: PUBLIC PROC [bb1, bb2: BoundBox, op: PointSetOp] RETURNS [newBB: BoundBox] = {
Dispatches to the appropriate one of the three procs below.
SELECT op FROM
union => newBB ← SVBoundBox.UnionCombineBoundBoxes[bb1, bb2];
intersection => newBB ← SVBoundBox.IntersectionCombineBoundBoxes[bb1, bb2];
difference => newBB ← SVBoundBox.DifferenceCombineBoundBoxes[bb1, bb2];
ENDCASE => ERROR;
};
END.