GGSequence.mesa
Copyright © 1986 by Xerox Corporation. All rights reserved.
Last edited by Bier on April 6, 1987 7:47:42 pm PDT
Contents: Sequences are a way to describe some part of a trajectory without actually pulling the trajectory apart. The new definition of sequence is that it is ANY subset of the parts of a trajectory (joints and/or segments). Procedures are provided which make sequences, perform boolean operations on them, and step through them.
Pier, May 12, 1987 6:34:07 pm PDT
DIRECTORY
GGBasicTypes, GGModelTypes, GGSegmentTypes, Imager, Rope;
GGSequence:
CEDAR
DEFINITIONS =
BEGIN
BoundBox: TYPE = GGBasicTypes.BoundBox;
Joint: TYPE = GGModelTypes.Joint;
Point: TYPE = GGBasicTypes.Point;
PointAndDone: TYPE = GGModelTypes.PointAndDone;
SelectionClass: TYPE = GGSegmentTypes.SelectionClass;
Segment: TYPE = GGSegmentTypes.Segment;
Sequence: TYPE = GGModelTypes.Sequence;
SequenceOfReal: TYPE = GGBasicTypes.SequenceOfReal;
SliceDescriptor: TYPE = GGModelTypes.SliceDescriptor;
StrokeEnd: TYPE = Imager.StrokeEnd;
StrokeJoint: TYPE = Imager.StrokeJoint;
Traj: TYPE = GGModelTypes.Traj;
TrajEnd: TYPE = GGModelTypes.TrajEnd; -- {lo, hi};
TrajPartType: TYPE = GGModelTypes.TrajPartType; -- {none, joint, controlPoint, segment};
CreateFromSegments:
PROC [traj: Traj, startSeg, endSeg:
NAT]
RETURNS [seq: Sequence];
The sequence created will include all of the segments from startSeg to endSeg inclusive, and all of the joints which they touch. startSeg and endSeg must be legal Sequence numbers for this trajectory. If the trajectory is closed, then startSeg > endSeg is allowed, in which case the segment sequence wraps around.
If startSeg = endSeg, then one segment is added.
If startSeg = endSeg + 1 (modulo the number of segments in traj), then the whole trajectory is selected.
Returns a sequences with only one contiguous part [start...end].
CreateJointToJoint:
PROC [traj: Traj, startJoint, endJoint:
NAT]
RETURNS [seq: Sequence];
IF the traj is open, then include all segments in the interval [startJoint..endJoint]. If the traj is closed, there are three cases: 1) IF startJoint = endJoint then select a single joint. 2) IF startJoint < endJoint then proceed as for an open traj (but there is no way to include the whole trajectory. 3) IF endJoint < startJoint, wrap around, selecting all segments above startJoint, all segments below endJoint, all joints above startJoint including startJoint, all joints below endJoint, including endJoint.
CreateEmpty:
PROC [traj: Traj]
RETURNS [seq: Sequence];
Returns a sequence belonging to traj, which refers to none of its parts.
CreateComplete: PROC [traj: Traj] RETURNS [seq: Sequence];
Copy: PROC [seq: Sequence] RETURNS [copy: Sequence];
CreateFromJoint:
PROC [traj: Traj, jointNum:
NAT]
RETURNS [seq: Sequence];
Returns a sequence belonging to traj, which refers to a single joint.
CreateFromSegment: PROC [traj: Traj, segNum: NAT] RETURNS [seq: Sequence];
CreateSimpleFromSegment: PROC [traj: Traj, segNum: NAT] RETURNS [seq: Sequence];
CreateFromControlPoint:
PROC [traj: Traj, segNum:
NAT, controlPointNum:
NAT]
RETURNS [seq: Sequence];
Returns a sequence belonging to traj, which refers to a single segment (and the joints at its endpoints).
Fundamentals
UpdateBoundBox: PROC [seq: Sequence];
ComputeBoundBox:
PROC [seq: Sequence]
RETURNS [box: BoundBox];
Compute the bounding box of all segments, joints, and control points mentioned in seq. Allow for control point size and stroke width.
ComputeTightBox:
PROC [seq: Sequence]
RETURNS [box: BoundBox];
Compute the bounding box of all segments in seq. Do NOT allow for control point size and stroke width.
Textual Description
Describe: PROC [seq: Sequence] RETURNS [rope: Rope.ROPE];
Procedures which mutate Segments (use with caution)
CopyInto:
PROC [to: Sequence, from: Sequence];
Returns a sequence belonging to traj, which refers to all of its parts.
FillInJoints:
PROC [seq: Sequence];
Ensures that, for each segment A in seq, both endjoints of A are in seq as well.
FillInControlPoints:
PROC [seq: Sequence];
Ensures that, for each segment A in seq, all control points of A are in seq as well.
TrimSelectedParts:
PROC [seq: Sequence,
selectedList:
LIST
OF
SliceDescriptor];
Modifies, mutes, and munges seq, so that it no longer includes any parts mentioned in selectedList. Used by GGAlign.RemoveMoving.
TrimSelectedControlPointSegments:
PROC [seq: Sequence,
selectedList:
LIST
OF
SliceDescriptor];
Modifies, mutes, and munges seq, so that it no longer includes any segments whose control points are mentioned in selectedList. Used by GGAlign.RemoveMoving.
TrimSelectedJointSegments:
PROC [seq: Sequence,
selectedList:
LIST
OF
SliceDescriptor];
Modifies, mutes, and munges seq, so that it no longer includes any segments whose joints are mentioned in selectedList. Used by GGAlign.RemoveMoving.
If jointOn then for all segments in seq, remove those that have a joint mentioned in seq. Otherwise, remove those segments that do NOT have a joint mentioned.
DDifference:
PROC [mutable, negative: Sequence];
This is a destructive form of the Difference operation. mutable ← mutable - negative.
Parts Routines
Union: PROC [a, b: Sequence] RETURNS [union: Sequence];
Intersection: PROC [a, b: Sequence] RETURNS [intersection: Sequence];
Difference: PROC [a, b: Sequence] RETURNS [aMinusB: Sequence];
TrajMovingParts: PROC [seq: Sequence] RETURNS [background, overlay, rubber, drag: Sequence];
AugmentParts: PROC [seq: Sequence, selectClass: SelectionClass];
Augment: PROC [seq: Sequence, trajEnd: TrajEnd, extend: BOOL] RETURNS [bigger: Sequence];
Queries
IsEmpty:
PROC [seq: Sequence]
RETURNS [
BOOL];
TRUE if the seq represents none of the joints, segments, and control points of its trajectory.
IsComplete:
PROC [seq: Sequence]
RETURNS [
BOOL];
TRUE if the seq represents all of the joints, segments, and control points of its trajectory.
IsObsolete:
PROC [seq: Sequence]
RETURNS [
BOOL];
TRUE if trajectory has changed size (number of joints, segments, or control points) since seq was made.
Overlap:
PROC [seq1, seq2: Sequence]
RETURNS [
BOOL];
RETURNS TRUE iff seq1 and seq2 share some joints or segments.
ContainsJoint: PROC [seq: Sequence, jointNum: NAT] RETURNS [BOOL];
ContainsSegment: PROC [seq: Sequence, segNum: NAT] RETURNS [BOOL];
ContainsSomeSegment:
PROC [seq: Sequence]
RETURNS [
BOOL];
Returns TRUE if the sequence contains the segment itself.
ContainsSegmentParts:
PROC [seq: Sequence, segNum:
NAT]
RETURNS [
BOOL];
Returns TRUE if the sequence contains any part of a segment, including its end joints, its control points, or the segment proper.
LastSegAndJoint: PROC [traj: Traj, trajEnd: TrajEnd] RETURNS [segAndJoint: Sequence];
UnpackOnePointSequence:
PROC [seq: Sequence]
RETURNS [isACP:
BOOL, segNum, cpNum, jointNum:
NAT];
seq is asserted to be either a single joint or a single control point. Return the [segNum, cpNum] pair or the jointNum as appropriate.
UnpackOneSegmentSequence: PROC [seq: Sequence] RETURNS [segNum: NAT];
UnpackSimpleSequence:
PROC [seq: Sequence]
RETURNS [success:
BOOL, partType: TrajPartType ← none, traj: Traj, joint: Joint ←
NIL, jointNum:
NAT ← 999, cp: Point ← [0,0], cpNum:
NAT ← 999, seg: Segment ←
NIL, segNum:
NAT ← 999];
seq is asserted to be a single segment. Return the segNum.
Generators
SequenceGenerator: TYPE = GGModelTypes.SequenceGenerator;
RunsInSequence:
PROC [seq: Sequence]
RETURNS [seqGen: SequenceGenerator, runCount:
NAT];
A run is a sequence with only one contiguous piece. In other words, each joint in the run touches at least one segment in the run (unless the run is a single joint), and each segment in the run touches at least one joint in the run (unless the run is a single segment). The run whose lowest joint has the lowest index will be returned first by NextSequence. The other runs will follow in ascending order.
NextSequence: PROC [seqGen: SequenceGenerator] RETURNS [seq: Sequence];
SegmentGenerator: TYPE = GGModelTypes.SegmentGenerator;
SegmentsInTraj:
PROC [traj: Traj]
RETURNS [segGen: SegmentGenerator];
Returns a generator for all segment in traj, beginning with segment 0.
SegmentsInSequence:
PROC [seq: Sequence]
RETURNS [segGen: SegmentGenerator];
Returns a generator for all segment in seq, beginning with the lowest numbered one (contrast this with OrderedSegmentsInSequence below).
OrderedSegmentsInSequence:
PROC [seq: Sequence]
RETURNS [segGen: SegmentGenerator];
Returns a generator for all segment in seq, beginning with the lowest numbered one (in the case of open trajectories), or the first segment that follows a segment that is not in seq (for closed trajectories). If seq.traj is complete and closed, then behaves like SegmentsInSequence.
NextSegment:
PROC [segGen: SegmentGenerator]
RETURNS [next: Segment];
Returns the next segment from segGen. segGen may have been produced by SegmentsInTraj, SegmentsInSequence or OrderedSegmentsInSequence.
SegAndIndex: TYPE = RECORD [seg: Segment, index: NAT];
NextSegmentAndIndex: PROC [segGen: SegmentGenerator] RETURNS [next: SegAndIndex];
ControlPointGenerator: TYPE = GGModelTypes.ControlPointGenerator;
ControlPointsInSequence: PROC [seq: Sequence] RETURNS [cpGen: ControlPointGenerator];
NextControlPoint: PROC [cpGen: ControlPointGenerator] RETURNS [next: PointAndDone];
NextSegNumAndCPNum: PROC [cpGen: ControlPointGenerator] RETURNS [segNum, cpNum: NAT, done: BOOL];
NextSegmentAndControlPointNum: PROC [cpGen: ControlPointGenerator] RETURNS [segAndCPNum: SegAndIndex];
JointGenerator: TYPE = GGModelTypes.JointGenerator;
JointsInSequence: PROC [seq: Sequence] RETURNS [jointGen: JointGenerator];
JointsInTraj: PROC [traj: Traj] RETURNS [jointGen: JointGenerator];
FirstJointNum:
PROC [run: Sequence]
RETURNS [
INT];
run had better be a run (a single non-empty contiguous sequence). Returns -1 if there are no joints in the run.
LastJointNum: PROC [run: Sequence, firstJointNum: INT] RETURNS [lastNum: INT];
FirstSegNum:
PROC [run: Sequence]
RETURNS [
INT];
run had better be a run (a single non-empty contiguous sequence).
LastSegNum:
PROC [run: Sequence, firstSegNum:
INT]
RETURNS [lastNum:
INT];
run had better be a run (a single non-empty contiguous sequence). Returns -1 if there are no joints in the run. Note that FirstJointNum[run] and LastJointNum[run] can be the same.
NextJoint: PROC [jointGen: JointGenerator] RETURNS [next: INT];
Style
SetStrokeWidth: PROC [seq: Sequence, strokeWidth: REAL];
GetStrokeWidth: PROC [seq: Sequence] RETURNS [strokeWidth: REAL];
SetStrokeEnd: PROC [seq: Sequence, strokeEnd: StrokeEnd];
GetStrokeEnd: PROC [seq: Sequence] RETURNS [strokeEnd: StrokeEnd];
SetStrokeColor: PROC [seq: Sequence, color: Imager.Color];
GetStrokeColor: PROC [seq: Sequence] RETURNS [color: Imager.Color];
SetStrokeDashed: PROC [seq: Sequence, dashed: BOOL, pattern: SequenceOfReal ← NIL, offset: REAL ← 0.0, length: REAL ← -1.0];
GetStrokeDashed: PROC [seq: Sequence] RETURNS [dashed: BOOL, pattern: SequenceOfReal, offset, length: REAL];
END.