GGObjects.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Last edited by Bier on November 7, 1985 9:25:13 pm PST
Contents: The procedural interface to the Gargoyle object modeler.
Stone, August 5, 1985 1:01:40 pm PDT
DIRECTORY
GGModelTypes,
Imager,
ImagerTransformation,
Rope,
Rosary;
GGObjects: CEDAR DEFINITIONS
IMPORTS Imager =
BEGIN
BoundBox: TYPE = GGModelTypes.BoundBox;
Cluster: TYPE = GGModelTypes.Cluster;
Joint: TYPE = GGModelTypes.Joint;
JointPair: TYPE = GGModelTypes.JointPair;
Outline: TYPE = GGModelTypes.Outline;
Point: TYPE = GGModelTypes.Point;
Scene: TYPE = GGModelTypes.Scene;
Sequence: TYPE = GGModelTypes.Sequence;
Traj: TYPE = GGModelTypes.Traj;
TrajEnd: TYPE = GGModelTypes.TrajEnd; -- {lo, hi}
Segment: TYPE = GGModelTypes.Segment;
Vector: TYPE = GGModelTypes.Vector;
Creating Trajectories and Outlines
The lifetime of a trajectory goes something like this: It begins as a single point. The sole purpose of this point is to be an "endpoint" to which the first segment can be attached. Subsequent segments are also added to endpoints, so this unifies the creation process. In Gargoyle, trajectories never appear at the top level of a scene; they are always part of an outline. It is suggested, then that each NewTraj call be followed immediately by an OutlineFromTraj call.
CreateTraj: PROC [point: Point] RETURNS [traj: Traj];
OutlineFromTraj: PROC [traj: Traj, lineEnds: Imager.StrokeEnd ← square, fillColor: Imager.Color ← Imager.black] RETURNS [outline: Outline];
OutlineFromTraj creates a simple outline with a single trajectory. The lineEnds of an open outline, or the fill color of closed outline are stored in the outline record.
To change the outline parameters later:
SetLineEnds: PROC [outline: Outline, lineEnds: Imager.StrokeEnd];
SetFillColor: PROC [outline: Outline, fillColor: Imager.Color];
Make segments using the procedures in GGSegments. Add them to a trajectory with AddSegment.
AddSegment: PROC [traj: Traj, trajEnd: TrajEnd, seg: Segment, segEnd: TrajEnd] RETURNS [success: BOOL];
Moves seg so that the specified end of seg coincides with the specified end of traj. In other words, seg is translated.
If success = FALSE, AddSegment sends an error message to GGError and returns.
DeleteSegment: PROC [traj: Traj, seg: Segment];
CloseWithSegment: PROC [traj: Traj, seg: Segment, segEnd: TrajEnd];
LikeAddSegment, except that here we rotate, scale, and translate traj as needed so that both of its endpoints coincide with the endpoints of traj (which must not already be closed). The endpoint correspondence is made so that the named (trajEnd) end of traj touches the named (segEnd) end of seg, leaving the unnamed ends to touch each other.
OpenAtSegment: PROC [traj: Traj, seg: Segment];
To make an outline with holes, use these:
AddHoles: PROC [outline: Outline, holes: LIST OF Outline];
outline may be a simple closed outline, or may already contain holes. holes must all be simple closed outlines. The trajectories are extracted from the holes outlines and become holes of outline.
Holes can be removed using Delete.
WeldTraj: PROC [fixed: Traj, fixedEnd: TrajEnd, moving: Traj, movingEnd: TrajEnd] RETURNS [longer: Traj];
SplitTraj: PROC [traj: Traj, jointOfSplit: NAT] RETURNS [loPiece, hiPiece: Traj];
Moves moving so that the specified end moving coincides with the specified end fixed. In other words, moving is translated.
ExtractTraj: PROC [original: Traj, start: INT, len: INT] RETURNS [piece: Traj];
Creates a new trajectory which is a subset of an existing trajectory.
CopyTraj: PROC [original: Traj] RETURNS [copy: Traj];
Cluster Operations
MakeCluster: PROC [entities: LIST OF REF ANY] RETURNS [newCluster: Cluster];
BreakCluster: PROC [oldCluster: Cluster] RETURNS [entities: LIST OF REF ANY];
Scene Operations
CreateScene: PROC [] RETURNS [scene: Scene];
AddOutline: PROC [scene: Scene, outline: Outline, priority: INT];
Add the given outline to the scene with the given priority (the higher the priority number, the closer the outline is to the front. If priority is -1, the outline will be the front-most entity.
AddCluster: PROC [scene: Scene, cluster: Cluster, priority: INT];
DeleteOutline: PROC [scene: Scene, outline: Outline];
Like AddOutline, but adds a cluster.
Browsing the Scene Hierarchy -- Generators
EntityGenerator: TYPE = GGModelTypes.EntityGenerator;
TopLevelEntities: PROC [scene: Scene] RETURNS [entityGenerator: EntityGenerator];
EntitiesInCluster: PROC [cluster: Cluster] RETURNS [entityGenerator: EntityGenerator];
NextEntity: PROC [g: EntityGenerator] RETURNS [next: REF ANY];
TrajGenerator: TYPE = GGModelTypes.TrajGenerator;
TrajsInScene: PROC [scene: Scene] RETURNS [trajGen: TrajGenerator];
Generates all of the trajectories in the scene, whereever they occur.
TrajsInOutline: PROC [outline: Outline] RETURNS [trajGen: TrajGenerator];
HasHoles: PROC [outline: Outline] RETURNS [BOOL];
Generates the fence and all of the holes of outline.
HolesOfOutline: PROC [outline: Outline] RETURNS [trajGen: TrajGenerator];
Generates all of the holes of outline.
FenceOfOutline: PROC [outline: Outline] RETURNS [fence: Traj];
Returns the unique fence trajectory of outline.
NextTraj: PROC [g: TrajGenerator] RETURNS [next: Traj];
SegmentGenerator: TYPE = GGModelTypes.SegmentGenerator;
SegmentsInTraj: PROC [traj: Traj] RETURNS [segGen: SegmentGenerator];
SegmentsInJointPair: PROC [traj: Traj, start: NAT, end: INT] RETURNS [segGen: SegmentGenerator];
Caution: start and end are joint numbers. The segments between the two named joints will be generated.
SegmentsInSequence: PROC [seq: Sequence] RETURNS [segGen: SegmentGenerator];
InMODRegion: PROC [test: NAT, start, end, mod: NAT] RETURNS [BOOL];
PreviousSegment: PROC [traj: Traj, segNum: NAT] RETURNS [prev: Segment];
PreviousSegmentNum: PROC [traj: Traj, segNum: NAT] RETURNS [prevNum: NAT];
FollowingSegmentNum: PROC [traj: Traj, segNum: NAT] RETURNS [followNum: NAT];
NextSegment: PROC [segGen: SegmentGenerator] RETURNS [next: Segment];
SegAndIndex: TYPE = RECORD [seg: Segment, index: NAT];
NextSegmentAndIndex: PROC [segGen: SegmentGenerator] RETURNS [next: SegAndIndex];
JointGenerator: TYPE = GGModelTypes.JointGenerator;
JointsInJointPair: PROC [traj: Traj, start: NAT, end: INT] RETURNS [jointGen: JointGenerator];
JointsInSequence: PROC [seq: Sequence] RETURNS [jointGen: JointGenerator];
JointsInTraj: PROC [traj: Traj] RETURNS [jointGen: JointGenerator];
NextJoint: PROC [jointGen: JointGenerator] RETURNS [next: INT];
BoundBoxGenerator: TYPE = GGModelTypes.BoundBoxGenerator;
BoundBoxesInScene: PROC [scene: Scene] RETURNS [bBoxGen: BoundBoxGenerator];
NextBox: PROC [g: BoundBoxGenerator] RETURNS [next: BoundBox];
Browsing the Scene Hierarchy -- Up and Down levels
OutlineOfTraj: PROC [traj: Traj] RETURNS [outline: Outline];
Up one level (traj -> outline). Finds the unique outline to which traj belongs.
Finding and Moving Joints and Segments
HiSegment: PROC [traj: Traj] RETURNS [highestIndex: NAT];
Returns traj.segCount-1 for both open and closed trajectories.
FetchSegment: PROC [traj: Traj, index: NAT] RETURNS [seg: Segment];
HiJoint: PROC [traj: Traj] RETURNS [highestIndex: NAT];
FollowingJoint: PROC [traj: Traj, index: NAT] RETURNS [nextIndex: NAT];
segCount for open trajectories, segCount -1 for closed trajectories.
FetchJointPos: PROC [traj: Traj, index: NAT] RETURNS [point: Point];
LastJointPos: PROC [traj: Traj] RETURNS [point: Point];
SetJointPos: PROC [traj: Traj, index: NAT, newPos: Point];
IsEndJoint: PROC [traj: Traj, index: NAT] RETURNS [BOOL];
Use sparingly
FetchJoint: PROC [traj: Traj, index: NAT] RETURNS [joint: Joint];
IndexOfJoint: PROC [joint: Joint, traj: Traj] RETURNS [index: INT];
Returns -1 if it doesn't exist.
IndexOfSegment: PROC [segment: Segment, traj: Traj] RETURNS [index: INT];
Returns -1 if it doesn't exist.
Sequences
CreateSimpleSequence: PROC [traj: Traj, start, end: NAT] RETURNS [seq: Sequence];
Returns a sequences with only one contiguous part [start...end].
CreateEmptySequence: PROC [traj: Traj] RETURNS [seq: Sequence];
CreateCompleteSequence: PROC [traj: Traj] RETURNS [seq: Sequence];
CreateSequenceFromJoint: PROC [traj: Traj, jointNum: NAT] RETURNS [seq: Sequence];
CreateSequenceFromSegment: PROC [traj: Traj, segNum: NAT] RETURNS [seq: Sequence];
Returns a sequence which represents the entire trajectory.
AddPart: PROC [seq: Sequence, start, end: NAT];
SequencesOverlap: PROC [seq1, seq2: Sequence] RETURNS [BOOL];
RETURNS TRUE iff seq1 and seq2 share some joints or segments.
CombineSequences: PROC [new, old: Sequence] RETURNS [union: Sequence, newMinusOld: Sequence];
IsEmptySequence: PROC [seq: Sequence] RETURNS [BOOL];
SequenceGenerator: TYPE = GGModelTypes.SequenceGenerator;
NextSequence: PROC [seqGen: SequenceGenerator] RETURNS [seq: Sequence];
InJointRange: PROC [index: NAT, seq: Sequence] RETURNS [BOOL];
Transforming Trajectories
TransformTraj: PROC [traj: Traj, transform: ImagerTransformation.Transformation];
Individually translates each joint and control point of the trajectory.
TransformSegment: PROC [seg: Segment, transform: ImagerTransformation.Transformation];
Individually translates each joint and control point of a segment.
TransformSequence: PROC [seq: Sequence, transform: ImagerTransformation.Transformation];
Individually translates each joint and control point of the subsequence of traj from start to end inclusive. Note: start and end are joint numbers. If end = start + 1, then a single segment will be altered.
TranslateSegment: PROC [seg: Segment, vector: Vector];
A convenience routine which does a TransformSegment, where transform is a simple translation.
Segment Style
SetStrokeWidth: PROC [seq: Sequence, strokeWidth: REAL];
SetColor: PROC [seq: Sequence, color: Imager.Color];
END.