DIRECTORY Atom, Feedback, FeedbackTypes, GGCoreTypes, GGHistoryTypes, GGHistoryTypesOpaque, GGModelTypes, GGOutline, GGParent, GGParseIn, GGProps, GGSlice, GGSliceOps, GGTraj, Imager, ImagerTransformation, IO, Rope; GGSliceOpsImpl: CEDAR PROGRAM IMPORTS Atom, Feedback, GGOutline, GGParent, GGParseIn, GGProps, --GGScene,-- GGSlice, GGSliceOps, GGTraj, ImagerTransformation, IO, Rope EXPORTS GGSliceOps, GGHistoryTypes = BEGIN OPEN GGModelTypes; noteNoMore: PUBLIC BOOL _ TRUE; debugHalt: PUBLIC BOOL _ FALSE; BoundBox: TYPE = GGCoreTypes.BoundBox; Change: PUBLIC TYPE = GGHistoryTypesOpaque.Change; -- exported to GGHistoryTypes HistoryEvent: TYPE = GGHistoryTypes.HistoryEvent; HistoryProc: TYPE = GGHistoryTypes.HistoryProc; SubEvent: TYPE = GGHistoryTypes.SubEvent; SubEventObj: TYPE = GGHistoryTypes.SubEventObj; StrokeEndRec: TYPE = RECORD [end: Imager.StrokeEnd]; -- TYPE = {square, butt, round} StrokeJointRec: TYPE = RECORD [joint: Imager.StrokeJoint]; -- TYPE = {miter, bevel, round} DashedRec: TYPE = RECORD [dashed: BOOL _ FALSE, pattern: SequenceOfReal, offset, length: REAL]; SequenceOfReal: TYPE = GGCoreTypes.SequenceOfReal; ArrowRec: TYPE = RECORD [leftDown, rightUp: BOOL _ FALSE]; OrientationRec: TYPE = RECORD [or: Orientation]; TransformRec: TYPE = RECORD [transform: Imager.Transformation, editConstraints: EditConstraints]; DebugHalt: SIGNAL = CODE; GetType: PUBLIC PROC [slice: Slice] RETURNS [type: ATOM] = {RETURN[slice.class.type]}; GetBoundBox: PUBLIC SliceBoundBoxProc = {RETURN[slice.class.getBoundBox[slice, parts]];}; GetTransformedBoundBox: PUBLIC SliceTransformedBoundBoxProc = {RETURN[slice.class.getTransformedBoundBox[slice, selectedParts, movingParts, transform]];}; GetTightBox: PUBLIC SliceTightBoxProc = {RETURN[slice.class.getTightBox[slice, parts]];}; Copy: PUBLIC SliceCopyProc = {RETURN[slice.class.copy[slice, parts]];}; Restore: PUBLIC SliceRestoreProc = {from.class.restore[from: from, to: to];}; Unlink: PUBLIC SliceUnlinkProc = {slice.class.unlink[slice];}; BuildPath: PUBLIC SliceBuildPathProc = {slice.class.buildPath[slice, transformParts, transform, moveTo, lineTo, curveTo, conicTo, arcTo, editConstraints];}; DrawBorder: PUBLIC SliceDrawBorderProc = {slice.class.drawBorder[slice, drawParts, transformParts, transform, dc, camera, quick, editConstraints];}; DrawParts: PUBLIC SliceDrawPartsProc = {slice.class.drawParts[slice, parts, dc, camera, quick];}; DrawTransform: PUBLIC SliceDrawTransformProc = {slice.class.drawTransform[slice, parts, dc, camera, transform, editConstraints ];}; DrawSelectionFeedback: PUBLIC SliceDrawSelectionFeedbackProc = {slice.class.drawSelectionFeedback[slice, selectedParts, hotParts, dc, camera, dragInProgress, caretIsMoving, hideHot, quick];}; DrawAttractorFeedback: PUBLIC SliceDrawAttractorFeedbackProc = {slice.class.drawAttractorFeedback[slice, attractorParts, selectedParts, dragInProgress, dc, camera, editConstraints];}; AttractorFeedbackBoundBox: PUBLIC SliceAttractorFeedbackBoundBoxProc = { IF slice.class.attractorFeedbackBoundBox = NIL THEN RETURN GGSlice.NoOpAttractorFeedbackBoundBox[slice, attractorParts, selectedParts, dragInProgress, camera, editConstraints] ELSE RETURN slice.class.attractorFeedbackBoundBox[slice, attractorParts, selectedParts, dragInProgress, camera, editConstraints]; }; SaveSelections: PUBLIC SliceSaveSelectionsProc = {slice.class.saveSelections[slice, parts, selectClass];}; RemakeSelections: PUBLIC SliceRemakeSelectionsProc = { parts _ slice.class.remakeSelections[slice, selectClass]; }; Transform: PUBLIC SliceTransformProc = { oldValue: REF TransformRec _ NEW[TransformRec]; oldValue.transform _ transform; -- defer inverting the transform until undo is performed oldValue.editConstraints _ editConstraints; slice.class.transform[slice, parts, transform, editConstraints, history]; GenericPropsUndo[op: $Transform, slice: slice, parts: parts, val: oldValue, history: history]; }; Describe: PUBLIC SliceDescribeProc = {RETURN[sliceD.slice.class.describe[sliceD]];}; DescribeHit: PUBLIC SliceDescribeHitProc = {RETURN[slice.class.describeHit[slice, hitData]];}; Fileout: PUBLIC SliceFileoutProc = {slice.class.fileout[slice, f];}; Filein: PUBLIC SliceFileinProc = {RETURN[slice.class.filein[f, version, router, camera]];}; IsEmptyParts: PUBLIC SliceIsEmptyPartsProc = { RETURN[sliceD.slice.class.isEmptyParts[sliceD]];}; IsCompleteParts: PUBLIC SliceIsCompletePartsProc = { RETURN[sliceD.slice.class.isCompleteParts[sliceD]];}; NewParts: PUBLIC SliceNewPartsProc = {RETURN[slice.class.newParts[slice, hitData, mode]];}; UnionParts: PUBLIC SliceUnionPartsProc = {RETURN[partsA.slice.class.unionParts[partsA, partsB]];}; DifferenceParts: PUBLIC SliceDifferencePartsProc = { RETURN[partsA.slice.class.differenceParts[partsA, partsB]];}; MovingParts: PUBLIC SliceMovingPartsProc = {[background, overlay, rubber, drag] _ slice.class.movingParts[slice, selectedParts, editConstraints, bezierDrag];}; AugmentParts: PUBLIC SliceAugmentPartsProc = { RETURN[sliceD.slice.class.augmentParts[sliceD, selectClass]];}; AlterParts: PUBLIC SliceAlterPartsProc = { RETURN[sliceD.slice.class.alterParts[sliceD, action]];}; SetSelectedFields: PUBLIC SliceSetSelectedFieldsProc = {sliceD.slice.class.setSelectedFields[sliceD, selected, selectClass];}; PointsInDescriptor: PUBLIC SlicePointsInDescriptorProc = { RETURN[sliceD.slice.class.pointsInDescriptor[sliceD]];}; WalkPointsInDescriptor: PUBLIC SliceWalkPointsInDescriptorProc = { sliceD.slice.class.walkPointsInDescriptor[sliceD, walkProc];}; PointPairsInDescriptor: PUBLIC SlicePointPairsInDescriptorProc = {RETURN[sliceD.slice.class.pointPairsInDescriptor[sliceD]];}; SegmentsInDescriptor: PUBLIC SliceSegmentsInDescriptorProc = {RETURN[sliceD.slice.class.segmentsInDescriptor[sliceD]];}; WalkSegments: PUBLIC SliceWalkSegmentsProc = {RETURN[slice.class.walkSegments[slice, walkProc]];}; NextPoint: PUBLIC SliceNextPointProc = {RETURN[slice.class.nextPoint[slice, pointGen]];}; NextPointPair: PUBLIC SliceNextPointPairProc = {RETURN[slice.class.nextPointPair[slice, pointPairGen]];}; NextSegment: PUBLIC SliceNextSegmentProc = {[seg, transform] _ slice.class.nextSegment[slice, segGen];}; ClosestPoint: PUBLIC SliceClosestPointProc = {[bestPoint, bestDist, bestNormal, hitData, success] _ sliceD.slice.class.closestPoint[sliceD, testPoint, tolerance];}; ClosestJointToHitData: PUBLIC SliceClosestJointToHitDataProc = {[jointD, point, normal] _ sliceD.slice.class.closestJointToHitData[sliceD, mapPoint, testPoint, hitData];}; ClosestPointAndTangent: PUBLIC SliceClosestPointAndTangentProc = {[bestPoint, bestDist, tangent, hitData, success] _ sliceD.slice.class.closestPointAndTangent[sliceD, testPoint, tolerance];}; ClosestSegment: PUBLIC SliceClosestSegmentProc = {[bestPoint, bestDist, bestNormal, hitData, success] _ sliceD.slice.class.closestSegment[sliceD, testPoint, tolerance];}; FilledPathsUnderPoint: PUBLIC SliceFilledPathsUnderPointProc = { IF slice.class.filledPathsUnderPoint = NIL THEN RETURN GGSlice.NoOpFilledPathsUnderPoint[slice, point, tolerance] ELSE { RETURN slice.class.filledPathsUnderPoint[slice, point, tolerance]; }; }; LineIntersection: PUBLIC SliceLineIntersectionProc = {[points, pointCount] _ sliceD.slice.class.lineIntersection[sliceD, line];}; CircleIntersection: PUBLIC SliceCircleIntersectionProc = {[points, pointCount] _ sliceD.slice.class.circleIntersection[sliceD, circle];}; HitDataAsSimpleCurve: PUBLIC SliceHitDataAsSimpleCurveProc = {RETURN[slice.class.hitDataAsSimpleCurve[slice, hitData]];}; SetDefaults: PUBLIC SliceSetDefaultsProc = { slice.class.setDefaults[slice, parts, defaults, history]; }; SetStrokeWidth: PUBLIC SliceSetStrokeWidthProc = { oldValue: REF REAL _ NEW[REAL _ slice.class.getStrokeWidth[slice, parts].strokeWidth]; box _ slice.class.setStrokeWidth[slice, parts, strokeWidth, history]; GenericPropsUndo[op: $SetStrokeWidth, slice: slice, parts: parts, val: oldValue, history: history]; RETURN[box]; }; GetStrokeWidth: PUBLIC SliceGetStrokeWidthProc = { RETURN slice.class.getStrokeWidth[slice, parts]; }; SetStrokeEnd: PUBLIC SliceSetStrokeEndProc = { oldValue: REF StrokeEndRec _ NEW[StrokeEndRec]; oldValue.end _ slice.class.getStrokeEnd[slice, parts].strokeEnd; slice.class.setStrokeEnd[slice, parts, strokeEnd, history]; GenericPropsUndo[op: $SetStrokeEnd, slice: slice, parts: parts, val: oldValue, history: history]; }; GetStrokeEnd: PUBLIC SliceGetStrokeEndProc = { RETURN slice.class.getStrokeEnd[slice, parts]; }; SetStrokeJoint: PUBLIC SliceSetStrokeJointProc = { oldValue: REF StrokeJointRec _ NEW[StrokeJointRec]; oldValue.joint _ slice.class.getStrokeJoint[slice, parts].strokeJoint; slice.class.setStrokeJoint[slice, parts, strokeJoint, history]; GenericPropsUndo[op: $SetStrokeJoint, slice: slice, parts: parts, val: oldValue, history: history]; }; GetStrokeJoint: PUBLIC SliceGetStrokeJointProc = { RETURN slice.class.getStrokeJoint[slice, parts]; }; SetStrokeColor: PUBLIC SliceSetStrokeColorProc = { oldValue: Imager.Color _ slice.class.getStrokeColor[slice, parts].color; slice.class.setStrokeColor[slice, parts, color, setHow, history]; GenericPropsUndo[op: $SetStrokeColor, slice: slice, parts: parts, val: oldValue, history: history]; }; GetStrokeColor: PUBLIC SliceGetStrokeColorProc = { RETURN slice.class.getStrokeColor[slice, parts]; }; SetFillColor: PUBLIC SliceSetFillColorProc = { oldValue: Imager.Color _ slice.class.getFillColor[slice, parts].color; slice.class.setFillColor[slice, parts, color, setHow, history]; GenericPropsUndo[op: $SetFillColor, slice: slice, parts: parts, val: oldValue, history: history]; }; GetFillColor: PUBLIC SliceGetFillColorProc = { RETURN slice.class.getFillColor[slice, parts]; }; SetArrows: PUBLIC SliceSetArrowsProc = { oldValue: REF ArrowRec _ NEW[ArrowRec]; [oldValue.leftDown, oldValue.rightUp] _ slice.class.getArrows[slice]; slice.class.setArrows[slice, parts, leftDown, rightUp, history]; GenericPropsUndo[op: $SetArrows, slice: slice, parts: parts, val: oldValue, history: history]; }; GetArrows: PUBLIC SliceGetArrowsProc = { RETURN slice.class.getArrows[slice]; }; SetDashed: PUBLIC SliceSetDashedProc = { oldValue: REF DashedRec _ NEW[DashedRec]; [oldValue.dashed, oldValue.pattern, oldValue.offset, oldValue.length] _ slice.class.getDashed[slice, parts]; slice.class.setDashed[slice, parts, dashed, pattern, offset, length, history]; GenericPropsUndo[op: $SetDashed, slice: slice, parts: parts, val: oldValue, history: history]; }; GetDashed: PUBLIC SliceGetDashedProc = { RETURN slice.class.getDashed[slice, parts]; }; SetOrientation: PUBLIC SliceSetOrientationProc = { oldValue: REF OrientationRec _ NEW[OrientationRec]; oldValue.or _ slice.class.getOrientation[slice, parts].orientation; success _ slice.class.setOrientation[slice, parts, orientation, history]; GenericPropsUndo[op: $SetOrientation, slice: slice, parts: NIL, val: oldValue, history: history]; }; GetOrientation: PUBLIC SliceGetOrientationProc = { RETURN slice.class.getOrientation[slice, parts]; }; PropWalkProc: TYPE = GGProps.PropWalkProc; ValFormat: TYPE = GGProps.ValFormat; leftDelimiter: CHAR = 032C; -- Boxcar rightDelimiter: CHAR = 007C; -- Bell FileoutSlice: PUBLIC PROC [f: IO.STREAM, slice: Slice] = { type: ATOM _ GGSliceOps.GetType[slice]; f.PutF["%g ", [rope[Atom.GetPName[type]]] ]; GGSliceOps.Fileout[slice, f]; IF NOT GGParent.IsParentType[type] THEN FileoutPList[f, slice]; }; FileoutPList: PROC [f: IO.STREAM, slice: Slice] = { FileoutProp: PROC [key: ATOM, val: REF] RETURNS [done: BOOL _ FALSE] = { r: Rope.ROPE; vf: ValFormat; [r, vf] _ GGProps.ToRope[key, val]; -- get val in rope form with format SELECT TRUE FROM Rope.Length[r]=0 => { RETURN; -- NIL value. Don't write property. }; vf=delimited => { f.PutF["(%g ", [rope[Atom.GetPName[key]]] ]; -- write (keyName and SP f.PutF["%g%g%g) ", [character[leftDelimiter]], [rope[r]], [character[rightDelimiter]] ]; }; vf=counted => { c: INT _ Rope.Length[r]; f.PutF["(%g ", [rope[Atom.GetPName[key]]] ]; -- write (keyName and SP f.PutF["[%g] %g) ", [integer[c]], [rope[r]] ]; }; ENDCASE => ERROR; }; buttonClassName: ATOM _ NIL; success: BOOL _ TRUE; f.PutRope[" pList: ( "]; -- write property list label (pList: ) and starting leftParen IF slice.props#NIL THEN [] _ GGProps.Walk[slice, GGSliceOps.NewParts[slice, NIL, slice], FileoutProp]; f.PutRope[")\n"] -- write closing rightParen of pList and CR }; FileinSlice: PUBLIC PROC [f: IO.STREAM, version: REAL, router: FeedbackTypes.MsgRouter, camera: GGModelTypes. Camera, class: SliceClass _ NIL] RETURNS [slice: Slice] = { className: Rope.ROPE _ "Traj"; -- needed for older files without classes type: ATOM; IF class=NIL THEN { -- read the class name IF version >= 8705.14 THEN { className _ GGParseIn.ReadWWord[f]; } ELSE { childCount: NAT; GGParseIn.ReadWRope[f, "(class:"]; className _ GGParseIn.ReadWWord[f]; GGParseIn.ReadWRope[f, ")"]; GGParseIn.ReadWRope[f, "["]; childCount _ GGParseIn.ReadWNAT[f]; GGParseIn.ReadWRope[f, "]:"]; GGParseIn.ReadWRope[f, "Data:"]; }; }; type _ SliceClassFromRope[className]; class _ GGSlice.FetchSliceClass[type]; slice _ class.filein[f, version, router, camera]; IF version>=8906.16 AND slice # NIL AND NOT GGParent.IsParentType[GGSliceOps.GetType[slice]] THEN FileinPList[f, version, router, slice]; }; SliceClassFromRope: PROC [className: Rope.ROPE] RETURNS [type: ATOM] = { RETURN[Atom.MakeAtom[className] ]; }; FileinPList: PROC [f: IO.STREAM, version: REAL, router: FeedbackTypes.MsgRouter, slice: Slice] = { key: ATOM; val: REF; nextChar: CHAR; keyName, valRope: Rope.ROPE; success: BOOL _ TRUE; GGParseIn.ReadWRope[f, "pList: ("]; -- read property list label pList: and starting leftParen DO -- loop until end of property list GGParseIn.ReadBlank[f]; -- advance to next property or end of pList nextChar _ f.GetChar[]; IF nextChar=') THEN EXIT; -- reached end of pList IF nextChar#'( THEN ERROR; -- do better than ERROR later keyName _ GGParseIn.ReadWWord[f]; key _ Atom.MakeAtom[keyName]; nextChar _ f.GetChar[]; -- Can't use GGParseIn.ReadChar because it skips non-printing chars like leftDelimiter. This should read SP nextChar _ f.GetChar[]; -- choices are leftDelimiter, [, or ) SELECT nextChar FROM leftDelimiter => { -- read up to the right delimiter StopProc: IO.BreakProc = { RETURN[IF char=rightDelimiter THEN break ELSE other]; }; valRope _ f.GetTokenRope[StopProc].token; nextChar _ f.GetChar[]; -- should be the rightDelimiter. Can't use GGParseIn.ReadChar because it skips non-printing chars GGParseIn.ReadChar[f, ')]; -- SyntaxError raised if fails }; '[ => { -- read byte count, then SP, then read "count" bytes c: INT _ f.GetInt[]; GGParseIn.ReadWRope[f, "] " ]; -- better be a bracket and a single space valRope _ f.GetRope[len: c, demand: TRUE]; GGParseIn.ReadChar[f, ')]; -- SyntaxError raised if fails }; ') => valRope _ NIL; -- already read the rightParen ENDCASE => ERROR; -- do better than ERROR later val _ IF valRope=NIL THEN NIL ELSE GGProps.FromRope[key, valRope]; GGProps.Put[slice, NIL, key, val]; ENDLOOP; }; PartsInBoundBox: PUBLIC PROC [slice: Slice, box: BoundBox] RETURNS [inParts: SliceDescriptor] = { SIGNAL Feedback.Problem[msg: "Not yet implemented"]; }; WithinBoundBox: PUBLIC PROC [slice: Slice, box: BoundBox] RETURNS [in: BOOL] = { epsilon: REAL = 0.072; -- 0.001 inches Within: PROC [test, bound: BoundBox] RETURNS [BOOL] = { RETURN [test.hiX <= bound.hiX+epsilon AND test.loX >= bound.loX-epsilon AND test.hiY <= bound.hiY+epsilon AND test.loY >= bound.loY-epsilon]; }; sliceBox: BoundBox _ slice.class.getTightBox[slice, NIL]; in _ Within[sliceBox, box]; }; IsOpen: PUBLIC PROC [slice: Slice] RETURNS [isOpen: BOOL _ FALSE] = { IF GetType[slice] # $Traj THEN RETURN[FALSE]; RETURN[GGTraj.GetTrajRole[slice] = open]; }; GenericPropsUndo: PROC [op: ATOM, slice: Slice, parts: SliceParts, val: REF, history: HistoryEvent] = { IF history#NIL THEN { changeRef: REF Change.changingprops _ NEW[Change.changingprops _ [changingprops[op, slice, parts, val] ] ]; Note[history, UndoProps, changeRef]; }; }; Note: PUBLIC PROC [event: HistoryEvent, historyProc: HistoryProc, historyData: REF Change] = { IF event = NIL THEN RETURN; IF debugHalt THEN SIGNAL DebugHalt; IF noteNoMore AND event.subevents#NIL AND event.subevents.first#NIL AND event.subevents.first.historyData.kind=capture THEN RETURN; event.subevents _ CONS[NEW[SubEventObj _ [historyProc, historyData]], event.subevents]; }; UndoProps: PROC [historyData: REF Change, currentEvent: HistoryEvent] = { propsData: REF Change.changingprops _ NARROW[historyData]; slice: Slice _ propsData.slice; parts: SliceParts _ propsData.parts; IF slice.class#NIL THEN { SELECT propsData.op FROM $SetStrokeWidth => { oldValue: REF REAL _ NARROW[propsData.oldValue]; [] _ GGSliceOps.SetStrokeWidth[slice, FixBogusParts[slice, parts], oldValue^, currentEvent]; -- restore old value }; $SetStrokeEnd => { oldValue: REF StrokeEndRec _ NARROW[propsData.oldValue]; GGSliceOps.SetStrokeEnd[slice, FixBogusParts[slice, parts], oldValue.end, currentEvent]; }; $SetStrokeJoint => { oldValue: REF StrokeJointRec _ NARROW[propsData.oldValue]; GGSliceOps.SetStrokeJoint[slice, FixBogusParts[slice, parts], oldValue.joint, currentEvent]; }; $SetStrokeColor => { oldValue: Imager.Color _ NARROW[propsData.oldValue]; GGSliceOps.SetStrokeColor[slice, FixBogusParts[slice, parts], oldValue, $Set, currentEvent]; }; $SetFillColor => { oldValue: Imager.Color _ NARROW[propsData.oldValue]; GGSliceOps.SetFillColor[slice, parts, oldValue, $Set, currentEvent]; }; $SetArrows => { oldValue: REF ArrowRec _ NARROW[propsData.oldValue]; GGSliceOps.SetArrows[slice, FixBogusParts[slice, parts], oldValue.leftDown, oldValue.rightUp, currentEvent]; }; $SetDashed => { oldValue: REF DashedRec _ NARROW[propsData.oldValue]; GGSliceOps.SetDashed[slice, FixBogusParts[slice, parts], oldValue.dashed, oldValue.pattern, oldValue.offset, oldValue.length, currentEvent]; }; $SetOrientation => { oldValue: REF OrientationRec _ NARROW[propsData.oldValue]; [] _ GGSliceOps.SetOrientation[slice, FixBogusParts[slice, parts], oldValue.or, currentEvent]; }; $Transform => { oldValue: REF TransformRec _ NARROW[propsData.oldValue]; transform: Imager.Transformation _ ImagerTransformation.Invert[oldValue.transform]; -- lazily evaluate the inverse [] _ GGSliceOps.Transform[slice, FixBogusParts[slice, parts], transform, oldValue.editConstraints, currentEvent]; }; ENDCASE; }; }; FixBogusParts: PROC [slice: Slice, bogusParts: SliceParts] RETURNS [goodParts: SliceParts]= { goodParts _ bogusParts; -- gonna fix it in place IF forgetBogusParts THEN RETURN; ERROR; <> }; forgetBogusParts: BOOL _ TRUE; IsDescriptorOfEnd: PUBLIC PROC [sliceD: SliceDescriptor] RETURNS [BOOL] = { jointNum: NAT; partType: TrajPartType; success: BOOL _ FALSE; IF sliceD = NIL THEN RETURN[FALSE]; SELECT GGSliceOps.GetType[sliceD.slice] FROM $Cluster => { trajD: SliceDescriptor; trajD _ GGParent.FirstIncludedChild[sliceD.slice, sliceD.parts, leaf, $Traj]; RETURN[IsDescriptorOfEnd[trajD]]; }; $Outline => { trajD: SliceDescriptor; [success, partType, trajD, ----, jointNum] _ GGOutline.UnpackSimpleDescriptor[sliceD]; RETURN[IF (NOT success OR partType#joint) THEN FALSE ELSE GGTraj.IsEndJoint[trajD.slice, jointNum]]; }; $Traj => { [success, partType, ----, ----, jointNum] _ GGTraj.UnpackSimpleDescriptor[sliceD.slice, sliceD.parts]; RETURN[IF (NOT success OR partType#joint) THEN FALSE ELSE GGTraj.IsEndJoint[sliceD.slice, jointNum]]; }; ENDCASE => RETURN[FALSE]; }; UnpackJoint: PUBLIC PROC [sliceD: SliceDescriptor] RETURNS [success: BOOL, trajD: SliceDescriptor, jointNum: INT] = { SELECT GGSliceOps.GetType[sliceD.slice] FROM $Cluster => { sliceD _ GGParent.FirstIncludedChild[sliceD.slice, sliceD.parts, leaf, $Outline]; [success, ----, trajD, ----, jointNum] _ GGOutline.UnpackSimpleDescriptor[sliceD]; }; $Outline => [success, ----, trajD, ----, jointNum] _ GGOutline.UnpackSimpleDescriptor[sliceD]; ENDCASE => RETURN [FALSE, NIL, -1]; }; UnpackSegment: PUBLIC PROC [sliceD: SliceDescriptor] RETURNS [success: BOOL, hitType: TrajPartType, traj: Slice, seg: Segment, segNum: NAT _ 999] = { trajD: SliceDescriptor; SELECT GGSliceOps.GetType[sliceD.slice] FROM $Cluster => { sliceD _ GGParent.FirstIncludedChild[sliceD.slice, sliceD.parts, leaf, $Outline]; [success, hitType, trajD, ----, ----, ----, ----, seg, segNum] _ GGOutline.UnpackSimpleDescriptor[sliceD]; traj _ trajD.slice; }; $Outline => { [success, hitType, trajD, ----, ----, ----, ----, seg, segNum] _ GGOutline.UnpackSimpleDescriptor[sliceD]; traj _ trajD.slice; }; $Traj => { [success, hitType, ----, ----, ----, ----, ----, seg, segNum] _ GGTraj.UnpackSimpleDescriptor[sliceD.slice, sliceD.parts]; }; ENDCASE => RETURN [FALSE, none, NIL, NIL, 999]; }; END. RGGSliceOpsImpl.mesa Contents: This module is the outer interface to slice class procs Copyright Σ 1988 by Xerox Corporation. All rights reserved. Pier, July 18, 1991 7:46 pm PDT Bier, December 2, 1991 11:13 am PST One-to-one correspondence between procs here and SliceClass procs. Clients should call through GGSliceOps instead of directly through class record. Calls the slice class walkSegments proc. The walkProc is called with each segment in the slice. If walkProc returns TRUE, the part of the slice that corresponds to the segment will be in the SliceDescriptor returned by WalkSegments. ClosestPoint is an expensive procedure. GGMultiGravity and GGOutline call it directly. ClosestSegment is an expensive procedure. GGMultiGravity and GGOutline call it directly. Describes those paths of slice, with non-NIL fill color, that contain point. Used by GGMultiGravityImpl for faces-preferred gravity, which is used for selections. Paths are listed near to far in overlap order. Style PUNT on undo for now Procedures implemented as a thin veneer on top of the basic class procs Property list format is: ( (key value) (key value) (key value) ... ) key is the printname of an ATOM, value has two possible formats, distinguishable by their leading byte: [count] countBytes printable ascii string of any length write "[c]" then "SP" then c bytes from r then ")" then "SP". Property list format is: ( (key value) (key value) (key value) ... ) key is the printname of an ATOM, value has two possible formats, distinguishable by their leading byte: [count] countBytes printable ascii string of any length Returns a descriptor of those parts of slice that are within box. Returns TRUE if all parts of slice are within box. Refuse to append any more subevents to a capture type subevent GGModelTypes.HistoryProc This proc is called by the Undo mechanism. It is called with a history event (currentEvent) which it passes on to record its undo operations, making undo an event (and thus undoable) in itself. Routines that operate on several classes, but aren't class procs Used by GGEventImplC.AddControlPoint. ΚΤ˜J™codešΟbœ9™AK™˜bKšŸ œžœœX˜„KšŸœžœœ„˜ΐKšŸœžœœ|˜ΈšŸœžœ'˜Hšžœ)ž˜.Kšžœžœu˜€Kšžœžœv˜—K˜—KšŸœžœœ=˜kšŸœžœœ˜6Kšœ9˜9Kšœ˜—šŸ œžœœ˜)K•StartOfExpansion4[m: ImagerTransformation.Transformation, v: VEC]šœ žœžœ˜/Kšœ ‘8˜XKšœ+˜+KšœI˜IKšœŸ œ?˜^Kšœ˜—KšŸœžœœžœ(˜UKšŸ œžœœžœ,˜_KšŸœžœœ%˜EKšŸœžœœžœ3˜\KšŸ œžœœžœ,˜bKšŸœžœœžœ/˜kKšŸœžœœžœ/˜\KšŸ œžœœžœ2˜cšŸœžœœ˜4Kšžœ7˜=—KšŸ œžœœw˜ŸšŸ œžœœ˜.Kšžœ œ˜?—šŸ œžœœ˜*Kšžœ œ˜8—KšŸœžœe˜~šŸœžœœ˜:Kšžœ2˜8—šŸœžœœ˜BKšœ>˜>—KšŸœžœœžœ6˜KšŸœžœœžœ4˜yšŸ œžœœžœ.˜cJ™(JšœLžœp™ΐ—KšŸ œžœœžœ+˜ZKšŸ œžœœžœ3˜jKšŸ œžœœA˜išŸ œžœœ{˜₯KšœW™W—KšŸœžœœp˜¬KšŸœžœœ‚˜ΐšŸœžœœ~˜¬KšœY™Y—šŸœžœœ˜@Kšœ)žœ§™ΣKšžœ%žœžœžœ;˜qšžœ˜Kšžœ<˜BK˜—K˜K˜—KšŸœžœœP˜‚KšŸœžœœT˜ŠKš ŸœžœœžΟtœ0’œ˜zKš™šŸ œžœœ˜-Kš™Kšœ9˜9Kšœ˜—šŸœžœœ˜3Kš œ žœžœžœžœ9˜VKšœE˜EKšœc˜cKšž’œ˜ Kšœ˜—šŸœžœœ˜3Kšž’œ)˜0Kšœ˜—šŸ œžœœ˜/Kšœ žœžœ˜/Kšœ@˜@Kšœ;˜;Kšœa˜aKšœ˜—šŸ œžœœ˜/Kšž’œ'˜.Kšœ˜—šŸœžœœ˜3Kšœ žœžœ˜3KšœF˜FKšœ?˜?Kšœc˜cKšœ˜—šŸœžœœ˜3Kšž’œ)˜0Kšœ˜—šŸœžœœ˜3KšœH˜HKšœA˜AKšœc˜cKšœ˜—šŸœžœœ˜3Kšž’œ)˜0Kšœ˜—šŸ œžœ˜/KšœF˜FKšœ?˜?Kšœa˜aKšœ˜—šŸ œžœœ˜/Kšž’œ'˜.Kšœ˜—šŸ œžœœ˜)Kšœ žœ žœ ˜'KšœE˜EKšœ@˜@Kšœ^˜^Kšœ˜—šŸ œžœœ˜)Kšžœ˜$Kšœ˜—šŸ œžœœ˜)Kšœ žœ žœ ˜)Kšœl˜lKšœN˜NKšœ^˜^Kšœ˜—šŸ œžœœ˜)Kšžœ%˜+Kšœ˜—šŸœžœœ˜3Kšœ žœžœ˜3KšœC˜CKšœI˜IKšœ;žœ#˜aKšœ˜—šŸœžœœ˜3Kšžœ*˜0Kšœ˜—K˜K™GK™Kšœžœ˜*Kšœ žœ˜$Kšœžœ ‘ ˜%Kšœžœ ‘˜$procš Ÿ œžœžœžœžœ˜:L–[slice: GGModelTypes.Slice]šœžœ˜'Lšœ,˜,Lšœ˜Kšžœžœžœ˜?Lšœ˜L˜—šŸ œžœžœžœ˜4L™™L™+—Lšœžœ™ ™FL™šœ&™&L™——L˜šŸ œžœžœžœžœžœžœ˜HLšœžœ˜ Lšœ˜Lšœ$‘#˜Gšžœžœž˜šœ˜L–[atom: ATOM]šžœ‘$˜,K˜—˜L–[atom: ATOM]šœ-‘˜EKšœY˜YK˜—˜Kšœžœ˜L–[atom: ATOM]šœ-‘˜Ešœ.˜.Kšœ=™=—K˜—Kšžœžœ˜—L˜—Lšœžœžœ˜šœ žœžœ˜L˜—Kšœ‘=˜VLšžœ žœžœ5žœ˜fKšœ‘+˜žœ ˜^Kšžœ žœžœžœ˜Kšžœ žœžœ ˜#K™>Kšžœ žœžœžœžœžœ0žœžœ˜ƒšœžœžœ˜(Kšœ.˜.—šœ˜K˜——šŸ œžœžœ(˜IKšœ™KšœΒ™ΒKšœ žœžœ˜:Kšœ˜Kšœ$˜$šžœ žœžœ˜šžœž˜šœŸœ˜Kšœ žœžœžœ˜0KšœŸœ?‘˜qK˜—šœŸ œ˜Kšœ žœžœ˜8Kš’ Ÿ œA˜XK˜—šœŸœ˜Kšœ žœžœ˜:Kš’ ŸœC˜\K˜—šœŸœ˜Kšœžœ˜4Kš’ œQ˜\K˜—šœ œ˜Kšœžœ˜4KšœD˜DK˜—šœŸ œ˜Kšœ žœ žœ˜4Kšœ Ÿ œY˜mK˜—šœŸ œ˜Kšœ žœ žœ˜5Kšœ Ÿ œx˜ŒK˜—šœŸœ˜Kšœ žœžœ˜:Kš’Ÿœ@˜^K˜—šœŸ œ˜Kšœ žœžœ˜8KšœT‘˜rKš’Ÿ œX˜qK˜—Kšžœ˜—K˜—K˜—K˜šΠbn œžœ(žœ˜]Kšœ‘˜0Kšžœžœžœ˜ Kšžœ˜šžœ&žœ˜0Kšœ%žœ ˜8Kšœžœžœ˜6Kšœžœžœžœ1˜_Kšœžœžœžœ˜0K˜š žœ žœžœ)žœ žœž˜UKš žœžœžœžœžœ,˜_Kšœ ˜ Kšœ!˜!Kšžœ˜—Kšžœžœžœžœ˜9Kšœž˜—K˜K˜—Kšœžœžœ˜K˜™@K˜—š Ÿœžœžœžœžœ˜KKšœ žœ˜Kšœ˜Kšœ ž œ˜Kš žœ žœžœžœžœ˜#šžœ"ž˜,˜ Kšœ˜KšœM˜MKšžœ˜!K˜—˜ Kšœ˜Kšœ‘œ œ ˜VKšžœžœžœ žœžœžœžœ+˜dK˜—˜ Kšœ‘œœ˜fKšžœžœžœ žœžœžœžœ,˜eK˜—Kšžœžœžœ˜—K˜K˜—š Ÿ œžœžœžœ žœ$žœ˜ušžœ"ž˜,šœ ˜ KšœQ˜QKšœ ‘œ ‘œ7˜RK˜—Kšœ‘œ ‘œ7˜^Kšžœžœžœžœ˜#—K˜K˜—š Ÿ œžœžœžœ žœ<žœ ˜•Kšœ%™%Jšœ˜šžœ"ž˜,šœ ˜ KšœQ˜QKš œ‘œ‘œ‘œ‘œ:˜jK˜J˜—šœ ˜ Jš œ‘œ‘œ‘œ‘œ:˜jK˜J˜—šœ ˜ Jš œ‘œ‘œ‘œ‘œ‘œK˜zJ˜—Jš žœžœžœžœžœ˜/—K˜K˜—K˜Kšžœ˜—…—S¦qΜ