DIRECTORY Atom, GGDescribe, GGInterfaceTypes, GGModelTypes, GGSegmentTypes, GGTouch, GGTraj, IO, Rope; GGDescribeImpl: CEDAR PROGRAM IMPORTS Atom, GGTouch, GGTraj, IO, Rope EXPORTS GGDescribe = BEGIN AlignmentPoint: TYPE = GGInterfaceTypes.AlignmentPoint; EntityGenerator: TYPE = GGModelTypes.EntityGenerator; FeatureData: TYPE = GGInterfaceTypes.FeatureData; GargoyleData: TYPE = GGInterfaceTypes.GargoyleData; Outline: TYPE = GGModelTypes.Outline; OutlineDescriptor: TYPE = GGModelTypes.OutlineDescriptor; Segment: TYPE = GGSegmentTypes.Segment; Sequence: TYPE = GGModelTypes.Sequence; SequenceGenerator: TYPE = GGModelTypes.SequenceGenerator; Slice: TYPE = GGModelTypes.Slice; SliceDescriptor: TYPE = GGModelTypes.SliceDescriptor; SliceParts: TYPE = GGModelTypes.SliceParts; TouchGroup: TYPE = GGSegmentTypes.TouchGroup; TouchItem: TYPE = GGSegmentTypes.TouchItem; TouchItemGenerator: TYPE = GGTouch.TouchItemGenerator; Traj: TYPE = GGModelTypes.Traj; TrajGenerator: TYPE = GGModelTypes.TrajGenerator; NotYetImplemented: PUBLIC SIGNAL = CODE; terseSlice: BOOL _ FALSE; DescribeFeature: PUBLIC PROC [feature: FeatureData, gargoyleData: GargoyleData] RETURNS [rope: Rope.ROPE] = { IF feature = NIL THEN RETURN["nothing"] ELSE { SELECT feature.resultType FROM outline => { outline: Outline _ NARROW[feature.shape, OutlineDescriptor].slice; tParts: SliceParts _ outline.class.newParts[outline, feature.hitPart, gargoyleData.drag.selectState]; rope _ outline.class.describe[outline, tParts]; }; slice => IF terseSlice THEN rope _ Rope.Concat[Atom.GetPName[NARROW[feature.shape, SliceDescriptor].slice.class.type], " slice"] ELSE { -- do this because feature doesn't carry hitParts for slices, so we ask the slice to tell us its hitParts and then describe itself using those parts tSlice: Slice _ NARROW[feature.shape, SliceDescriptor].slice; tParts: SliceParts _ tSlice.class.newParts[tSlice, feature.hitPart, gargoyleData.drag.selectState]; rope _ tSlice.class.describe[tSlice, tParts]; }; distanceLine => rope _ "distance line"; slopeLine => rope _ "slope line"; angleLine => rope _ "angle line"; symmetryLine => rope _ "symmetry line"; radiiCircle => rope _ "compass circle"; intersectionPoint => { firstObj, secondObj: Rope.ROPE; alignPoint: AlignmentPoint _ NARROW[feature.shape]; line1: FeatureData _ alignPoint.curve1; line2: FeatureData _ alignPoint.curve2; tangent: BOOL _ alignPoint.tangent; IF line1 = NIL AND line2 = NIL THEN { rope _ IO.PutFR["the anchor"]; } ELSE { firstObj _ IF line1 # NIL THEN DescribeSourceFeature[line1, gargoyleData] ELSE "unknown"; secondObj _ IF line2 # NIL THEN DescribeSourceFeature[line2, gargoyleData] ELSE "unknown"; IF tangent THEN rope _ IO.PutFR["a %g/%g tangency point", [rope[firstObj]], [rope[secondObj]] ] ELSE rope _ IO.PutFR["a %g/%g intersection point", [rope[firstObj]], [rope[secondObj]] ]; }; }; midpoint => { seqPart: GGInterfaceTypes.SequencePart _ NARROW[feature.hitPart]; segNum: NAT _ seqPart.segNum; rope _ IO.PutFR["midpoint of segment %g", [integer[segNum]]]; }; anchor => { rope _ IO.PutFR["anchor"]; }; ENDCASE => ERROR; }; }; DescribeSourceFeature: PUBLIC PROC [feature: FeatureData, gargoyleData: GargoyleData] RETURNS [rope: Rope.ROPE] = { IF feature = NIL THEN RETURN["nothing"] ELSE { SELECT feature.type FROM outline => rope _ "outline"; slice => rope _ Rope.Concat[Atom.GetPName[NARROW[feature.shape, SliceDescriptor].slice.class.type], " slice"]; distanceLine => rope _ "distance line"; slopeLine => rope _ "slope line"; angleLine => rope _ "angle line"; symmetryLine => rope _ "symmetry line"; radiiCircle => rope _ "compass circle"; intersectionPoint => { firstObj, secondObj: Rope.ROPE; firstObj _ IF NARROW[feature.shape, AlignmentPoint].curve1 # NIL THEN DescribeSourceFeature[NARROW[feature.shape, AlignmentPoint].curve1, gargoyleData] ELSE "unknown"; secondObj _ IF NARROW[feature.shape, AlignmentPoint].curve2 # NIL THEN DescribeSourceFeature[NARROW[feature.shape, AlignmentPoint].curve2, gargoyleData] ELSE "unknown"; rope _ IO.PutFR["a %g/%g intersection point", [rope[firstObj]], [rope[secondObj]] ]; }; midpoint => rope _ IO.PutFR["midpoint of segment ???"]; ENDCASE => ERROR; }; }; DescribeTraj: PUBLIC PROC [traj: Traj] RETURNS [text: Rope.ROPE] = { text _ SELECT traj.role FROM open => IO.PutFR["a %g-segment open trajectory", [integer[traj.segCount]]], fence => IO.PutFR["a %g-segment fence", [integer[traj.segCount]]], hole => IO.PutFR["a %g-segment hole", [integer[traj.segCount]]], ENDCASE => ""; }; DescribeJoint: PUBLIC PROC [traj: Traj, jointNum: NAT] RETURNS [text: Rope.ROPE] = { end: BOOL; end _ GGTraj.IsEndJoint[traj, jointNum]; IF end THEN text _ IO.PutFR["end joint %g on ", [integer[jointNum]] ] ELSE text _ IO.PutFR["joint %g on ", [integer[jointNum]] ]; text _ Rope.Concat[text, DescribeSegment[traj, IF GGTraj.HiJoint[traj]=jointNum AND traj.role=open THEN jointNum-1 ELSE jointNum]]; }; DescribeControlPoint: PUBLIC PROC [traj: Traj, segNum: NAT, cpNum: NAT] RETURNS [text: Rope.ROPE] = { text _ Rope.Cat[IO.PutFR["control point %g on ", [integer[cpNum]]], DescribeSegment[traj, segNum] ]; }; DescribeSegment: PUBLIC PROC [traj: Traj, segNum: NAT] RETURNS [text: Rope.ROPE] = { IF segNum=LAST[NAT] THEN text _ Rope.Cat["a segment on ", DescribeTraj[traj]] ELSE { seg: Segment _ GGTraj.FetchSegment[traj, segNum]; text _ Rope.Cat[seg.class.describe[seg, TRUE, TRUE, TRUE, NIL], IO.PutFR[" segment %g on ", [integer[segNum]]], DescribeTraj[traj]]; }; }; DescribeSequence: PUBLIC PROC [seq: Sequence] RETURNS [text: Rope.ROPE] = { text _ Rope.Cat[IO.PutFR["One or more parts of "], DescribeTraj[seq.traj]]; }; DescribeItem: PROC [f: IO.STREAM, item: TouchItem] = { SELECT item.touchingPartType FROM joint => f.PutF["Item: joint on %g", [rope[DescribeTraj[NARROW[item.traj]]]]]; segment => f.PutF["Item: segment on %g", [rope[DescribeTraj[NARROW[item.traj]]]]]; ENDCASE => ERROR; }; DescribeTouchGroup: PUBLIC PROC [group: TouchGroup] RETURNS [text: Rope.ROPE] = { f: IO.STREAM; touchGen: TouchItemGenerator; f _ IO.ROS[]; f.PutF["TouchGroup: (%1.2f, %1.2f)\n", [real[group.point.x]], [real[group.point.y]]]; touchGen _ GGTouch.AllTouchItems[group]; FOR item: TouchItem _ GGTouch.NextTouchItem[touchGen], GGTouch.NextTouchItem[touchGen] UNTIL item = NIL DO f.PutChar[IO.TAB]; DescribeItem[f, item]; f.PutChar[IO.CR]; ENDLOOP; text _ IO.RopeFromROS[f]; }; END. ΠGGDescribeImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Last edited by Bier on January 26, 1987 3:38:48 pm PST Contents: Printing out descriptions of gargoyle objects onto text streams, for debugging and feedback. Pier, November 20, 1986 10:54:51 am PST Describes one of the possible two segments this joint is on text _ Rope.Cat[Atom.GetPName[seg.class.type], IO.PutFR[" segment %g on ", [integer[segNum]]], DescribeTraj[traj]]; Κν˜code™Kšœ Οmœ1™˜nKšœ'˜'Kšœ!˜!Kšœ!˜!Kšœ'˜'Kšœ'˜'šœ˜Kšœžœ˜š œ žœžœ)žœžœžœ5˜—Kšžœ ˜—š œ žœžœ)žœžœžœ5˜˜Kšžœ ˜—KšœžœK˜TK˜—Kšœžœ"˜7Kšžœžœ˜—K˜—K˜K˜—š Ÿ œžœžœžœ žœ˜Dšœ˜šžœ ž˜KšœžœA˜KKšœ žœ7˜BKšœžœ6˜@Kšžœ˜——K˜K˜—š Ÿ œžœžœžœžœ žœ˜TKšœžœ˜ Kšœ(˜(Kšžœžœžœ0˜EKšžœžœ-˜;š œ/žœžœžœ žœ ˜ƒK™;—K˜K˜—šŸœžœžœžœ žœžœ žœ˜eKšœžœR˜dK˜K˜—š Ÿœžœžœžœžœ žœ˜Tš žœžœžœžœ6žœ˜TKšœ1˜1Kš œ(žœžœžœžœžœB˜„Kšœ/žœB™sK˜—K˜K˜—š Ÿœžœžœžœ žœ˜KKšœžœ9˜KK˜K˜—šŸ œžœžœžœ˜6Kšžœž˜!Kšœ8žœ˜NKšœ<žœ˜RKšžœžœ˜K˜K˜—š Ÿœžœžœžœ žœ˜QKšœžœžœ˜ Kšœ˜Kšœžœžœ˜ KšœU˜UKšœ(˜(šžœTžœžœž˜jKšœ žœžœ˜Kšœ˜Kšœ žœžœ˜—Kšžœ˜Kšœžœ˜K˜—K˜Kšžœ˜K˜K˜K˜—…—ξ!«