DIRECTORY GGBasicTypes, GGCoreTypes, GGInterfaceTypes, GGModelTypes, GGSegmentTypes, Imager, ImagerPath, ImagerTransformation, IO, Rope, Rosary; GGTraj: CEDAR DEFINITIONS = BEGIN StrokeJoint: TYPE = Imager.StrokeJoint; BoundBox: TYPE = GGCoreTypes.BoundBox; Camera: TYPE = GGModelTypes.Camera; Circle: TYPE = GGBasicTypes.Circle; EditConstraints: TYPE = GGModelTypes.EditConstraints; FenceHoleOpen: TYPE = GGModelTypes.FenceHoleOpen; HitType: TYPE = GGModelTypes.TrajPartType; Joint: TYPE = GGSegmentTypes.Joint; Line: TYPE = GGCoreTypes.Line; Point: TYPE = GGBasicTypes.Point; Scene: TYPE = GGModelTypes.Scene; Segment: TYPE = GGSegmentTypes.Segment; SelectedObjectData: TYPE = GGSegmentTypes.SelectedObjectData; SelectionClass: TYPE = GGSegmentTypes.SelectionClass; Slice: TYPE = GGModelTypes.Slice; SliceClass: TYPE = GGModelTypes.SliceClass; SliceClassObj: TYPE = GGModelTypes.SliceClassObj; SliceDescriptor: TYPE = GGModelTypes.SliceDescriptor; SliceDescriptorObj: TYPE = GGModelTypes.SliceDescriptorObj; SliceObj: TYPE = GGModelTypes.SliceObj; SliceParts: TYPE = GGModelTypes.SliceParts; TrajData: TYPE = GGModelTypes.TrajData; TrajParts: TYPE = GGModelTypes.TrajParts; TrajPartType: TYPE = GGModelTypes.TrajPartType; TrajEnd: TYPE = GGModelTypes.TrajEnd; Vector: TYPE = GGBasicTypes.Vector; SegCPSequence: TYPE = REF SegCPSequenceObj; SegCPSequenceObj: TYPE = RECORD [ cPoints: SEQUENCE len: NAT OF ShowPoint]; ShowPoint: TYPE = RECORD [cPoint: Point, show: BOOL _ TRUE]; TrajHitData: TYPE = REF TrajHitDataObj; TrajHitDataObj: TYPE = RECORD [ hitType: HitType, segNum: INT, cpNum: INT, jointNum: INT, hitPoint: Point ]; RunProc: TYPE = PROC [run: SliceDescriptor] RETURNS [traj: Slice]; CreateTraj: PROC [point: Point] RETURNS [slice: Slice]; CreateTrajFromData: PROC [role: FenceHoleOpen, segCount: NAT, segments: Rosary.ROSARY, joints: Rosary.ROSARY, extraPoints: LIST OF Joint, visibleJoints: BOOL _ TRUE, strokeJoint: Imager.StrokeJoint _ round, loArrow, hiArrow: BOOL _ FALSE, selectedInPart: SelectedObjectData _ [FALSE, FALSE, FALSE, FALSE]] RETURNS [slice: Slice]; AddSegment: PROC [slice: Slice, trajEnd: TrajEnd, seg: Segment, segEnd: TrajEnd] RETURNS [success: BOOL]; CloseWithSegment: PROC [slice: Slice, seg: Segment, segEnd: TrajEnd]; CloseByDistorting: PROC [slice: Slice, distortEnd: TrajEnd]; DeleteControlPoints: PROC [trajD: SliceDescriptor, scene: Scene] RETURNS [bBox: BoundBox]; DeleteSequence: PROC [seq: SliceDescriptor] RETURNS [smallerOutline: Slice, openTrajOutlines: LIST OF Slice]; ReplaceFirstRun: PROC [trajD: SliceDescriptor, runProc: RunProc, segmentsOnly: BOOL, selectNewRuns: BOOL] RETURNS [newOutline: Slice]; OnlyChild: PROC [slice: Slice] RETURNS [BOOL]; SetTrajRole: PROC [traj: Slice, role: FenceHoleOpen]; GetTrajRole: PROC [traj: Slice] RETURNS [role: FenceHoleOpen]; CopyTrajFromRun: PROC [slice: Slice, run: TrajParts] RETURNS [copy: Slice]; CopyTrajFromRange: PROC [slice: Slice, start: INT, len: INT] RETURNS [piece: Slice]; Concat: PROC [fixed: Slice, fixedEnd: TrajEnd, moving: Slice, movingEnd: TrajEnd] RETURNS [longer: Slice]; SpliceIn: PROC [runDescriptor: SliceDescriptor, slice: Slice] RETURNS [newSlice: Slice]; ReverseTraj: PROC [slice: Slice]; IsClockwiseTraj: PROC [slice: Slice] RETURNS [BOOL]; IsClockwiseTrajTransformSeq: PROC [descriptor: SliceDescriptor, transform: ImagerTransformation.Transformation] RETURNS [BOOL]; DrawConstrained: PROC [dc: Imager.Context, selDescriptor: SliceDescriptor, segNum: NAT, seg: Segment, transform: ImagerTransformation.Transformation, entire, lo, hi: BOOL, controlPoints: GGBasicTypes.BitVector, editConstraints: EditConstraints, lineTo: ImagerPath.LineToProc, curveTo: ImagerPath.CurveToProc, conicTo: ImagerPath.ConicToProc, arcTo: ImagerPath.ArcToProc] RETURNS [cPointsInSeg: SegCPSequence]; DrawPolyline: PROC [dc: Imager.Context, traj: Slice]; ConstrainJoint: PROC [slice: Slice, editConstraints: EditConstraints, jointNum: NAT] RETURNS [constrained: BOOL]; ConstrainCP: PROC [slice: Slice, editConstraints: EditConstraints, segNum: NAT, cpNum: NAT] RETURNS [constrained: BOOL]; MatchShape: PROC [traj1, traj2: Slice] RETURNS [BOOL]; FetchSegment: PROC [slice: Slice, index: NAT] RETURNS [seg: Segment]; FetchSegmentTraj: PROC [trajData: TrajData, index: NAT] RETURNS [seg: Segment]; FetchJoint: PROC [slice: Slice, index: NAT] RETURNS [joint: Joint]; FetchJointPos: PROC [slice: Slice, index: NAT] RETURNS [point: Point]; FetchJointPosTraj: PROC [trajData: TrajData, index: NAT] RETURNS [point: Point]; FetchJointNormal: PROC [slice: Slice, index: NAT] RETURNS [normal: Vector]; LastJointPos: PROC [slice: Slice] RETURNS [point: Point]; SetJointPos: PROC [slice: Slice, index: NAT, newPos: Point]; HiSegment: PROC [slice: Slice] RETURNS [highestIndex: NAT]; HiSegmentTraj: PROC [trajData: TrajData] RETURNS [highestIndex: NAT]; HiJoint: PROC [slice: Slice] RETURNS [highestIndex: NAT]; HiJointTraj: PROC [trajData: TrajData] RETURNS [highestIndex: NAT]; PreviousSegment: PROC [slice: Slice, segNum: NAT] RETURNS [prev: Segment]; PreviousSegmentNum: PROC [slice: Slice, segNum: NAT] RETURNS [prevNum: INT]; FollowingSegmentNum: PROC [slice: Slice, segNum: NAT] RETURNS [followNum: INT]; FollowingJoint: PROC [slice: Slice, index: NAT] RETURNS [nextIndex: INT]; IsEndJoint: PROC [slice: Slice, index: NAT] RETURNS [BOOL]; SaveSelection: PROC [slice: Slice, selectClass: SelectionClass, scene: Scene]; SaveSelectionInSequence: PROC [descriptor: SliceDescriptor, selectClass: SelectionClass]; SaveSelectionInParts: PROC [slice: Slice, parts: SliceParts, selectClass: SelectionClass]; ClearSelection: PROC [slice: Slice, selectClass: SelectionClass]; ClearSelections: PROC [slice: Slice]; RemakeSelection: PROC [slice: Slice, selectClass: SelectionClass] RETURNS [parts: SliceParts]; UnpackSimpleDescriptor: PROC [traj: Slice, parts: SliceParts] RETURNS [success: BOOL _ FALSE, partType: TrajPartType _ none, trajData: TrajData, joint: Joint _ NIL, jointNum: NAT _ 999, cp: Point _ [0,0], cpNum: NAT _ 999, seg: Segment _ NIL, segNum: NAT _ 999]; UnpackHitData: PROC [hitData: REF ANY] RETURNS [hitType: HitType, segNum, cpNum, jointNum: INT, hitPoint: Point]; NearestSegment: PROC [testPoint: Point, descriptor: SliceDescriptor, tolerance: REAL] RETURNS [bestDist: REAL, bestSeg: NAT, bestPoint: Point, bestNormal: Vector, success: BOOL]; NearestJoint: PROC [testPoint: Point, descriptor: SliceDescriptor, tolerance: REAL] RETURNS [bestDist: REAL, bestJoint: NAT, bestPoint: Point, bestNormal: Vector, success: BOOL]; NearestControlPoint: PROC [testPoint: Point, descriptor: SliceDescriptor, tolerance: REAL] RETURNS [bestDist: REAL, bestSeg: NAT, bestControlPoint: NAT, bestPoint: Point, bestNormal: Vector, success: BOOL]; IndexOfJoint: PROC [joint: Joint, slice: Slice] RETURNS [index: INT]; IndexOfSegment: PROC [segment: Segment, slice: Slice] RETURNS [index: INT]; END. GGTraj.mesa Contents: Procedures to implement the Traj Slice Class. Trajectories consist of Segments. Copyright Σ 1986, 1987 by Xerox Corporation. All rights reserved. Pier, February 17, 1988 12:03:17 pm PST Bier, June 26, 1989 9:44:20 pm PDT Routine Creation 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. In Gargoyle, trajectories never appear at the top level of a scene; they are always part of an outline. Usually a CreateTraj call will be followed immediately by a GGScene.CreateOutline call. Trajectory-Only Routines Will there be an arrowhead on the lo end of traj? On the hi end? 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 Feedback and returns. Like AddSegment, except that here we rotate, scale, and translate seg 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 hi end of traj touches the named (segEnd) end of seg, leaving the other ends to touch each other. Move either the first joint or the last joint (depending on the distortEnd argument) to coincide with the other end. This will reduce the number of joints in the trajectory by one (making all sequences which refer to this trajectory obsolete. new traj will have role = fence. Deletes selected control points and returns bounding box of area requiring refresh. Deletes those trajectory parts described in seq, and returns the new smaller Outline (possibly still with holes) and new trajectories enclosed in Outlines, that are pieces of the original seq.traj. Used by GGEventImplE.SetCurveAux. trajD summarizes those active bits in trajD.slice that are set. Find the first run of active bits, and replace it as described by runProc. If segmentsOnly is set, ignore runs that consist of a single joint. If selectNewRuns is set, set the "normal" bits of any new segments that are added. Returns TRUE if traj's parent outline has no holes. Building Trajectories from Parts Creates a new trajectory from the consecutive set of segments described by run. All of the segments are copied, so run's slice is untouched. Like CopyTrajFromRun, but we specify the run with a start segment and a number of segments. Creates a new trajectory by concatenating two existing trajectories. Copies are made, so fixed and moving are unchanged. moving is translated so that its movingEnd touches the fixedEnd of fixed. Run describes a part of its traj that is to be replaced by slice. The result is similar to Rope.Cat[Rope.Substr[...], newRope, Rope.Substr[...]] except that a Traj can be a circular structure. Orientation Drawing Transforming Accessing Parts Returns traj.segCount-1 for both open and closed trajectories. Returns -1 if no PreviousSegmentNum Returns -1 if no FollowingSegmentNum segCount for open trajectories, segCount -1 for closed trajectories. Returns -1 if no FollowingJoint Parts Set all of the selection fields to FALSE (faster than several calls to ClearSelection). Hit Testing Use sparingly: Returns -1 if it doesn't exist. Κά˜Icodešœ ™ šΟnœS™[KšœB™BK™'K™"—K™šΟk ˜ Jšœužœ˜†—K˜Kšœžœž œž˜!˜K˜Kšœ žœ˜'Kšœ žœ˜&Kšœžœ˜#Kšœžœ˜#Kšœžœ ˜5Iprocšœžœ˜1Kšœ žœ˜*Kšœžœ˜#Kšœžœ˜Kšœžœ˜!Kšœžœ˜!Kšœ žœ˜'Kšœžœ%˜=Kšœžœ!˜5Kšœžœ˜!Kšœ žœ˜+Kšœžœ˜1Kšœžœ ˜5Kšœžœ#˜;Kšœ žœ˜'Kšœ žœ˜+Kšœ žœ˜'Kšœ žœ˜)Kšœžœ˜/Kšœ žœ˜%Kšœžœ˜#K˜Kšœžœžœ˜+šœžœžœ˜!Kšœ žœžœžœ ˜)—Kš œ žœžœžœžœ˜K˜K™ šœžœ žœ˜KKšœ™—š œžœžœžœžœ˜TKšœ[™[—šœžœFžœ˜jKšœΔ™Δ—šœžœ0žœ˜XKšœΑ™Α—K˜K™ Kš œžœ˜!Kšœžœžœžœ˜4KšœžœOžœžœ˜K™K™Kš œžœ>žœPžœΙžœ˜™Kš œžœ#˜5K™K™ Kš œžœ<žœžœžœ˜qKš  œžœ:žœ žœžœžœ˜xK˜Kš œžœžœžœ˜6K˜Kšœ™Kš œžœžœžœ˜EKšœžœžœžœ˜OKš œžœžœžœ˜CKš œžœžœžœ˜FKšœžœžœžœ˜PKšœžœžœžœ˜KKš œžœžœ˜9Kš œžœžœ˜™>—Kšœžœžœžœ˜9Kš œžœžœžœ˜CKšœžœžœžœ˜Jš œžœžœžœ žœ˜LKšœ#™#—š œžœžœžœ žœ˜OKšœ$™$—š œžœžœžœ žœ˜IK™DKšœ™—Kš  œžœžœžœžœ˜;K˜K™Kš œžœ;˜NKšœžœ<˜YKšœžœ@˜ZKšœžœ-˜Ašœžœ˜%Kšœ#žœ/™W—Kšœžœ-žœ˜^K˜K™ Kšœžœ"žœ ž œDžœ žœ"žœžœ žœ˜†Kš  œžœ žœžœžœ-žœ˜qKšœžœ<žœžœ žœ žœ1žœ˜²Kš œžœ<žœžœ žœ žœ1žœ˜²Kšœžœ<žœžœ žœ žœžœ1žœ˜ΞK™Kšœ™š œžœžœ žœ˜EK™—Kšœžœ"žœ žœ˜KK˜Kšžœ˜K˜—…—τ/π