DIRECTORY GGBasicTypes, GGCoreTypes, GGInterfaceTypes, GGModelTypes, GGSegmentTypes, GGTrajTypes, 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; MakeCurveProc: TYPE = GGTrajTypes.MakeCurveProc; 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 = GGTrajTypes.RunProc; 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]; SegToSegMatchCp: PROC [seg: Segment, traj: Slice, makeCurve: MakeCurveProc, type: ATOM]; SegAndCpsToSegs: PROC [seg: Segment, traj: Slice, makeCurve: MakeCurveProc, type: ATOM]; 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, 1992 by Xerox Corporation. All rights reserved. Pier, February 17, 1988 12:03:17 pm PST Bier, January 28, 1993 3:39 pm PST 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. Replace segs with new segs made by 'makeCurve' maintaining control point data if possible. Variable type is a hint as to the type of curve that 'makeCurve' will make. Segments that are already of this type will be left alone. Like SegToSegMatchCp, but every control point of the old segment is used as an endpoint for a new segment, so one old segment may produce many new segments. 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. ΚH–(cedarcode) style•NewlineDelimiter ™codešœ ™ KšΟnœS™[Kšœ Οeœ=™HK™'K™"K™—šΟk ˜ Jšœ‚Ÿœœœœ˜“—K˜šœŸœŸ œŸ˜!K˜Kšœ Ÿœ˜'Kšœ Ÿœ˜&KšœŸœ˜#KšœŸœ˜#KšœŸœ ˜5IprocšœŸœ˜1Kšœ Ÿœ˜*KšœŸœ˜#KšœŸœ˜KšœŸœ˜0KšœŸœ˜!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˜—…—Δ2΄