GGBoundBoxImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Last edited by Bier on August 14, 1985 10:38:53 pm PDT
Contents: Procedures for creating and combining bounding boxes for refresh efficiency.
DIRECTORY
GGBoundBox,
GGModelTypes,
GGInterfaceTypes,
GGObjects,
GGSelect,
GGShapes,
Imager;
GGBoundBoxImpl: CEDAR PROGRAM
IMPORTS GGBoundBox, GGObjects, GGSelect, GGShapes, Imager
EXPORTS GGBoundBox =
BEGIN
BoundBox: TYPE = REF BoundBoxObj;
BoundBoxObj: TYPE = GGModelTypes.BoundBoxObj;
EntityGenerator: TYPE = GGModelTypes.EntityGenerator;
GargoyleData: TYPE = GGInterfaceTypes.GargoyleData;
Cluster: TYPE = GGModelTypes.Cluster;
Outline: TYPE = GGModelTypes.Outline;
Segment: TYPE = GGModelTypes.Segment;
SegmentGenerator: TYPE = GGObjects.SegmentGenerator;
Sequence: TYPE = GGModelTypes.Sequence;
Traj: TYPE = GGModelTypes.Traj;
CreateBoundBox: PUBLIC PROC [loX, loY, hiX, hiY: REAL] RETURNS [bBox: BoundBox] = CHECKED {
bBox ← NEW[BoundBoxObj ← [loX, loY, hiX, hiY]];
};
CopyBoundBox: PUBLIC PROC [bBox: BoundBox] RETURNS [copy: BoundBox] = CHECKED {
copy ← NEW[BoundBoxObj ← [bBox.loX, bBox.loY, bBox.hiX, bBox.hiY]];
};
BoundBoxOfTraj: PUBLIC PROC [traj: Traj] RETURNS [bBox: BoundBox] = CHECKED {
Computes it from segment boxes.
segGen: SegmentGenerator;
segmentBoxes: LIST OF BoundBox ← NIL;
segGen ← GGObjects.SegmentsInTraj[traj];
FOR seg: Segment ← GGObjects.NextSegment[segGen], GGObjects.NextSegment[segGen] UNTIL seg = NIL DO
segmentBoxes ← CONS[seg.boundBox, segmentBoxes];
ENDLOOP;
bBox ← BoundBoxOfBoxes[segmentBoxes];
};
EnlargeBoundBox: PUBLIC PROC [bBox: BoundBox, by: BoundBox] = CHECKED {
IF by.loX < bBox.loX THEN bBox.loX ← by.loX;
IF by.hiX > bBox.hiX THEN bBox.hiX ← by.hiX;
IF by.loY < bBox.loY THEN bBox.loY ← by.loY;
IF by.hiY > bBox.hiY THEN bBox.hiY ← by.hiY;
};
AdjustForJoints: PUBLIC PROC [bBox: BoundBox] = {
side: REAL ← GGModelTypes.jointSize/2.0;
bBox.loX ← bBox.loX-side;
bBox.loY ← bBox.loY-side;
bBox.hiX ← bBox.hiX+side;
bBox.hiY ← bBox.hiY+side;
};
BoundBoxOfBoxes: PUBLIC PROC [list: LIST OF BoundBox] RETURNS [bigBox: BoundBox] = CHECKED {
IF list = NIL THEN RETURN[NIL];
bigBox ← NEW[BoundBoxObj];
bigBox.loX ← list.first.loX;
bigBox.hiX ← list.first.hiX;
bigBox.loY ← list.first.loY;
bigBox.hiY ← list.first.hiY;
FOR bBoxList: LIST OF BoundBox ← list.rest, bBoxList.rest UNTIL bBoxList = NIL DO
IF bBoxList.first.loX < bigBox.loX THEN bigBox.loX ← bBoxList.first.loX;
IF bBoxList.first.hiX > bigBox.hiX THEN bigBox.hiX ← bBoxList.first.hiX;
IF bBoxList.first.loY < bigBox.loY THEN bigBox.loY ← bBoxList.first.loY;
IF bBoxList.first.hiY > bigBox.hiY THEN bigBox.hiY ← bBoxList.first.hiY;
ENDLOOP;
};
BoundBoxOfSelected: PUBLIC PROC [gargoyleData: GargoyleData] RETURNS [bigBox: BoundBox] = {
entityGen: EntityGenerator;
entity: REF ANY;
nextBox: BoundBox;
entityGen ← GGSelect.SelectedEntities[gargoyleData, normal];
entity ← GGObjects.NextEntity[entityGen];
WITH entity SELECT FROM
cluster: Cluster => bigBox ← GGBoundBox.CopyBoundBox[cluster.boundBox];
outline: Outline => bigBox ← GGBoundBox.CopyBoundBox[outline.boundBox];
traj: Traj => bigBox ← GGBoundBox.CopyBoundBox[traj.boundBox];
seq: Sequence => bigBox ← GGBoundBox.CopyBoundBox[seq.traj.boundBox]; -- finer grain comes later
ENDCASE => ERROR;
FOR entity ← GGObjects.NextEntity[entityGen], GGObjects.NextEntity[entityGen] UNTIL entity = NIL DO
WITH entity SELECT FROM
cluster: Cluster => nextBox ← cluster.boundBox;
outline: Outline => nextBox ← outline.boundBox;
traj: Traj => nextBox ← traj.boundBox;
seq: Sequence => nextBox ← seq.traj.boundBox; -- finer grain comes later
ENDCASE => ERROR;
IF nextBox.loX < bigBox.loX THEN bigBox.loX ← nextBox.loX;
IF nextBox.hiX > bigBox.hiX THEN bigBox.hiX ← nextBox.hiX;
IF nextBox.loY < bigBox.loY THEN bigBox.loY ← nextBox.loY;
IF nextBox.hiY > bigBox.hiY THEN bigBox.hiY ← nextBox.hiY;
ENDLOOP;
};
DrawBoundBox: PUBLIC PROC [dc: Imager.Context, bBox: BoundBox] = CHECKED {
GGShapes.DrawRectangle[dc, bBox.loX, bBox.loY, bBox.hiX, bBox.hiY];
};
Clip: PUBLIC PROC [dc: Imager.Context, bBox: BoundBox] = CHECKED {
Imager.ClipRectangle[dc, [bBox.loX, bBox.loY, (bBox.hiX-bBox.loX), (bBox.hiY-bBox.loY)]];
};
END.