<> <> <> <> <<>> DIRECTORY GGBasicTypes, Feedback, GGInterfaceTypes, GGModelTypes, GGOutline, GGScene, GGSelect, GGSegmentTypes, GGSequence, GGSlice, GGTraj, GGUtility, GList, Imager, Rope; GGOutlineImplB: CEDAR PROGRAM IMPORTS Feedback, GGScene, GGSlice, GGOutline, GGSelect, GGSequence, GGTraj, GGUtility, GList EXPORTS GGOutline = BEGIN OPEN GGOutline; BitVector: TYPE = GGBasicTypes.BitVector; BoundBox: TYPE = GGBasicTypes.BoundBox; CameraData: TYPE = GGModelTypes.CameraData; Circle: TYPE = GGBasicTypes.Circle; Color: TYPE = Imager.Color; ControlPointGenerator: TYPE = GGModelTypes.ControlPointGenerator; FeatureData: TYPE = GGInterfaceTypes.FeatureData; GGData: TYPE = GGInterfaceTypes.GGData; Joint: TYPE = GGSegmentTypes.Joint; JointGenerator: TYPE = GGModelTypes.JointGenerator; Line: TYPE = GGBasicTypes.Line; AlignBag: TYPE = GGInterfaceTypes.AlignBag; Outline: TYPE = REF OutlineObj; OutlineObj: TYPE = GGModelTypes.OutlineObj; OutlineClass: TYPE = REF OutlineClassObj; OutlineClassObj: TYPE = GGModelTypes.OutlineClassObj; OutlineData: TYPE = GGOutline.OutlineData; OutlineDataObj: TYPE = GGOutline.OutlineDataObj; OutlineDescriptor: TYPE = GGModelTypes.OutlineDescriptor; OutlineDescriptorObj: TYPE = GGModelTypes.OutlineDescriptorObj; OutlineParts: TYPE = REF OutlinePartsObj; OutlinePartsObj: TYPE = GGOutline.OutlinePartsObj; OutlineSequence: TYPE = GGSelect.OutlineSequence; OutlineSequenceGenerator: TYPE = GGSelect.OutlineSequenceGenerator; Point: TYPE = GGBasicTypes.Point; PointGenerator: TYPE = GGModelTypes.PointGenerator; PointPairGenerator: TYPE = GGModelTypes.PointPairGenerator; Scene: TYPE = GGModelTypes.Scene; Segment: TYPE = GGSegmentTypes.Segment; SegmentGenerator: TYPE = GGModelTypes.SegmentGenerator; SelectMode: TYPE = GGModelTypes.SelectMode; SelectionClass: TYPE = GGSegmentTypes.SelectionClass; Sequence: TYPE = GGModelTypes.Sequence; Slice: TYPE = GGModelTypes.Slice; SliceClass: TYPE = REF SliceClassObj; SliceClassObj: TYPE = GGModelTypes.SliceClassObj; SliceDescriptor: TYPE = GGModelTypes.SliceDescriptor; SliceParts: TYPE = GGModelTypes.SliceParts; Traj: TYPE = REF TrajObj; TrajEnd: TYPE = GGModelTypes.TrajEnd; TrajGenerator: TYPE = REF TrajGeneratorObj; TrajGeneratorObj: TYPE = GGModelTypes.TrajGeneratorObj; TrajObj: TYPE = GGModelTypes.TrajObj; TrajPartType: TYPE = GGModelTypes.TrajPartType; TriggerBag: TYPE = GGInterfaceTypes.TriggerBag; Vector: TYPE = GGBasicTypes.Vector; <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <<>> Problem: PUBLIC SIGNAL [msg: Rope.ROPE] = Feedback.Problem; <> <<>> UnpackOnePointDescriptor: PUBLIC PROC [outlineD: SliceDescriptor] RETURNS [traj: Traj, isACP: BOOL, segNum, cpNum, jointNum: NAT] = { <> parts: OutlineParts; theSeq: Sequence; IF outlineD = NIL OR outlineD.slice.class.type#$Outline THEN RETURN[NIL, FALSE, 999, 999, 999]; parts _ NARROW[outlineD.parts]; traj _ NIL; FOR list: LIST OF Sequence _ parts.seqs, list.rest UNTIL list = NIL DO IF list.first # NIL THEN { IF traj # NIL THEN RETURN[NIL, FALSE, 999, 999, 999] ELSE { theSeq _ list.first; traj _ theSeq.traj; [isACP, segNum, cpNum, jointNum] _ GGSequence.UnpackOnePointSequence[theSeq]; }; }; ENDLOOP; }; <> <> <> <> <> <> <> <> <> <> <> <> <<[success, partType, traj, joint, jointNum, cp, cpNum, seg, segNum] _ GGSequence.UnpackSimpleSequence[theSeq];>> <<};>> <<};>> <> <<};>> <<>> UnpackSimpleDescriptor: PUBLIC PROC [outlineD: SliceDescriptor] RETURNS [success: BOOL, partType: TrajPartType, traj: Traj, joint: Joint _ NIL, jointNum: NAT _ 999, cp: Point, cpNum: NAT _ 999, seg: Segment _ NIL, segNum: NAT _ 999] = { parts: OutlineParts; -- list of seq theSeq: Sequence; IF outlineD = NIL OR outlineD.slice.class.type#$Outline THEN RETURN[FALSE, joint, NIL, NIL, 999, [0,0]]; parts _ NARROW[outlineD.parts]; traj _ NIL; FOR list: LIST OF Sequence _ parts.seqs, list.rest UNTIL list = NIL DO IF list.first # NIL THEN { IF traj # NIL THEN RETURN[FALSE, joint, NIL, NIL, 999, [0,0]] ELSE { theSeq _ list.first; traj _ theSeq.traj; [success, partType, traj, joint, jointNum, cp, cpNum, seg, segNum] _ GGSequence.UnpackSimpleSequence[theSeq]; }; }; ENDLOOP; }; UnpackOneSegmentDescriptor: PUBLIC PROC [outlineD: SliceDescriptor] RETURNS [traj: Traj, segNum: NAT] = { <> parts: OutlineParts; theSeq: Sequence; IF outlineD = NIL OR outlineD.slice.class.type#$Outline THEN RETURN[NIL, 999]; parts _ NARROW[outlineD.parts]; traj _ NIL; FOR list: LIST OF Sequence _ parts.seqs, list.rest UNTIL list = NIL DO IF list.first # NIL THEN { IF traj # NIL THEN RETURN[NIL, 999] ELSE { theSeq _ list.first; traj _ theSeq.traj; [segNum] _ GGSequence.UnpackOneSegmentSequence[theSeq]; }; }; ENDLOOP; }; FindTrajInDescriptor: PUBLIC PROC [outlineD: OutlineDescriptor, traj: Traj] RETURNS [seq: Sequence] = { outlineParts: OutlineParts; outlineParts _ NARROW[outlineD.parts]; FOR list: LIST OF Sequence _ outlineParts.seqs, list.rest UNTIL list = NIL DO IF list.first # NIL AND list.first.traj = traj THEN RETURN[list.first]; ENDLOOP; RETURN[NIL]; }; PartsFromSequence: PUBLIC PROC [outline: Outline, seq: Sequence] RETURNS [sliceParts: SliceParts] = { realParts: OutlineParts; ptr: LIST OF Sequence; trajGen: GGModelTypes.TrajGenerator; sliceParts _ realParts _ NEW[OutlinePartsObj]; [realParts.seqs, ptr] _ GGUtility.StartSequenceList[]; trajGen _ TrajsInOutline[outline]; FOR traj: Traj _ GGScene.NextTraj[trajGen], GGScene.NextTraj[trajGen] UNTIL traj = NIL DO IF traj = seq.traj THEN [realParts.seqs, ptr] _ GGUtility.AddSequence[seq, realParts.seqs, ptr] ELSE [realParts.seqs, ptr] _ GGUtility.AddSequence[NIL, realParts.seqs, ptr]; ENDLOOP; }; DescriptorFromSequence: PUBLIC PROC [outline: Outline, seq: Sequence] RETURNS [sliceD: OutlineDescriptor] = { outlineParts: SliceParts; outlineParts _ PartsFromSequence[outline, seq]; sliceD _ GGSlice.DescriptorFromParts[outline, outlineParts]; }; <> <> <<};>> <<>> CopyParts: PUBLIC PROC [outline: Outline, parts: SliceParts] RETURNS [copy: SliceParts] = { realParts, realCopyParts: OutlineParts; copySeq: Sequence; ptr: LIST OF Sequence; realParts _ NARROW[parts]; copy _ realCopyParts _ NEW[OutlinePartsObj]; [realCopyParts.seqs, ptr] _ GGUtility.StartSequenceList[]; FOR list: LIST OF Sequence _ realParts.seqs, list.rest UNTIL list = NIL DO IF list.first = NIL THEN [realCopyParts.seqs, ptr] _ GGUtility.AddSequence[NIL, realCopyParts.seqs, ptr] ELSE { copySeq _ GGSequence.Copy[list.first]; [realCopyParts.seqs, ptr] _ GGUtility.AddSequence[copySeq, realCopyParts.seqs, ptr] }; ENDLOOP; }; <> <> <> <> <> <> <> <> <<};>> <<>> AddHole: PUBLIC PROC [outline: Outline, hole: Traj] RETURNS [holier: Outline] = { <> <> holyData: OutlineData; holier _ outline.class.copy[outline]; holyData _ NARROW[holier.data, OutlineData]; holyData.children _ AppendTrajList[holyData.children, LIST[hole]]; hole.parent _ holier; hole.role _ hole; UpdateBoundBox[holier]; }; ReplaceFence: PUBLIC PROC [outline: Outline, newFence: Traj] RETURNS [newOutline: Outline] = { <> newData: OutlineData; holeGen: TrajGenerator; newTraj: Traj; newOutline _ GGOutline.CreateOutline[newFence, NARROW[outline.data, OutlineData].fillColor]; newData _ NARROW[newOutline.data]; holeGen _ HolesOfOutline[outline]; FOR hole: Traj _ GGScene.NextTraj[holeGen], GGScene.NextTraj[holeGen] UNTIL hole = NIL DO newTraj _ GGTraj.CopyTraj[hole]; newData.children _ AppendTrajList[newData.children, LIST[newTraj]]; newTraj.parent _ newOutline; ENDLOOP; UpdateBoundBox[newOutline]; }; ReplaceHole: PUBLIC PROC [outline: Outline, oldHole, newHole: Traj] RETURNS [newOutline: Outline] = { <> newData: OutlineData; holeGen: TrajGenerator; newTraj, fence: Traj; fence _ FenceOfOutline[outline]; newTraj _ GGTraj.CopyTraj[fence]; newOutline _ CreateOutline[newTraj, NARROW[outline.data, OutlineData].fillColor]; newData _ NARROW[newOutline.data]; holeGen _ HolesOfOutline[outline]; FOR hole: Traj _ GGScene.NextTraj[holeGen], GGScene.NextTraj[holeGen] UNTIL hole = NIL DO IF hole = oldHole THEN { newData.children _ AppendTrajList[newData.children, LIST[newHole]]; newHole.parent _ newOutline; } ELSE { newTraj _ GGTraj.CopyTraj[hole]; newData.children _ AppendTrajList[newData.children, LIST[newTraj]]; newTraj.parent _ newOutline; }; ENDLOOP; UpdateBoundBox[newOutline]; }; OutlineOfTraj: PUBLIC PROC [traj: Traj] RETURNS [outline: Outline] = { <> outline _ traj.parent; }; TrajectoriesOfOutline: PUBLIC PROC [outline: Slice] RETURNS [children: LIST OF Traj] = { IF outline.class.type#$Outline THEN ERROR; -- temporary check children _ NARROW[outline.data, OutlineData].children; }; SaveSelectionsInOutline: PUBLIC PROC [outline: Slice, scene: Scene] = { outlineD: OutlineDescriptor; outlineParts: OutlineParts; <> IF outline.class.type#$Outline THEN ERROR; outlineD _ GGSelect.FindSelectedSlice[outline, scene, hot]; ClearSelectionInOutline[outline, hot]; IF outlineD # NIL THEN { outlineParts _ NARROW[outlineD.parts]; FOR seqList: LIST OF Sequence _ outlineParts.seqs, seqList.rest UNTIL seqList = NIL DO IF seqList.first#NIL THEN GGTraj.SaveSelectionInSequence[seqList.first, hot]; ENDLOOP; }; <> outlineD _ GGSelect.FindSelectedSlice[outline, scene, normal]; ClearSelectionInOutline[outline, normal]; IF outlineD # NIL THEN { outlineParts _ NARROW[outlineD.parts]; FOR seqList: LIST OF Sequence _ outlineParts.seqs, seqList.rest UNTIL seqList = NIL DO IF seqList.first#NIL THEN GGTraj.SaveSelectionInSequence[seqList.first, normal]; ENDLOOP; }; <> outlineD _ GGSelect.FindSelectedSlice[outline, scene, active]; ClearSelectionInOutline[outline, active]; IF outlineD # NIL THEN { outlineParts _ NARROW[outlineD.parts]; FOR seqList: LIST OF Sequence _ outlineParts.seqs, seqList.rest UNTIL seqList = NIL DO IF seqList.first#NIL THEN GGTraj.SaveSelectionInSequence[seqList.first, active]; ENDLOOP; }; }; ClearSelectionInOutline: PROC [outline: Slice, selectClass: SelectionClass] = { trajGen: GGModelTypes.TrajGenerator; IF outline.class.type#$Outline THEN ERROR; trajGen _ TrajsInOutline[outline]; FOR traj: Traj _ GGScene.NextTraj[trajGen], GGScene.NextTraj[trajGen] UNTIL traj = NIL DO GGTraj.ClearSelection[traj, selectClass]; ENDLOOP; }; RemakeSelectionsFromOutline: PUBLIC PROC [outline: Outline, scene: Scene] = { <> trajGen: GGModelTypes.TrajGenerator; trajGen _ TrajsInOutline[outline]; FOR traj: Traj _ GGScene.NextTraj[trajGen], GGScene.NextTraj[trajGen] UNTIL traj = NIL DO <> GGTraj.RemakeSelection[traj, scene, hot]; <> GGTraj.RemakeSelection[traj, scene, normal]; <> GGTraj.RemakeSelection[traj, scene, active]; ENDLOOP; }; SequencesOfOutline: PUBLIC PROC [sliceD: OutlineDescriptor] RETURNS [seqList: LIST OF Sequence] = { outlineParts: OutlineParts _ NARROW[sliceD.parts]; ptr: LIST OF Sequence; [seqList, ptr] _ GGUtility.StartSequenceList[]; FOR list: LIST OF Sequence _ outlineParts.seqs, list.rest UNTIL list = NIL DO IF list.first # NIL THEN [seqList, ptr] _ GGUtility.AddSequence[list.first, seqList, ptr]; ENDLOOP; }; RemoveTraj: PUBLIC PROC [outlineD: OutlineDescriptor, traj: Traj] RETURNS [newD: OutlineDescriptor] = { <> outlineParts: OutlineParts _ NARROW[outlineD.parts]; seq: Sequence; FOR list: LIST OF Sequence _ outlineParts.seqs, list.rest UNTIL list = NIL DO IF list.first#NIL AND list.first.traj = traj THEN { seq _ list.first; GOTO Done; }; REPEAT Done => { newSeqs: LIST OF Sequence _ NARROW[GList.Subst[NIL, seq, outlineParts.seqs]]; newParts: SliceParts _ NEW[OutlinePartsObj _ [newSeqs]]; newD _ GGSlice.DescriptorFromParts[outlineD.slice, newParts]; }; FINISHED => newD _ outlineD; ENDLOOP; }; <<>> UnpackHitData: PUBLIC PROC [hitData: REF ANY] RETURNS [traj: Traj, hitType: TrajPartType, segNum, cpNum, jointNum: INT, hitPoint: Point] = { <> outlineHitData: OutlineHitData _ NARROW[hitData]; traj _ outlineHitData.traj; hitType _ outlineHitData.hitType; segNum _ outlineHitData.segNum; cpNum _ outlineHitData.cpNum; jointNum _ outlineHitData.jointNum; hitPoint _ outlineHitData.hitPoint; }; <> <> <> <> <> <> <<};>> <<>> <> HasHoles: PUBLIC PROC [outline: Outline] RETURNS [BOOL] = { data: OutlineData _ NARROW[outline.data]; RETURN[data.children.rest # NIL]; }; FenceOfOutline: PUBLIC PROC [outline: Outline] RETURNS [fence: Traj] = { <> data: OutlineData _ NARROW[outline.data]; RETURN[data.children.first]; }; HolesOfOutline: PUBLIC PROC [outline: Outline] RETURNS [trajGen: TrajGenerator] = { <> data: OutlineData _ NARROW[outline.data]; list: LIST OF Traj _ data.children.rest; trajGen _ NEW[TrajGeneratorObj _ [ list: list ]]; }; TrajsInOutline: PUBLIC PROC [outline: Outline] RETURNS [trajGen: TrajGenerator] = { <> data: OutlineData _ NARROW[outline.data]; list: LIST OF Traj _ data.children; trajGen _ NEW[TrajGeneratorObj _ [ list: list ]]; }; END.