DIRECTORY SVAssembly, SVScene, SVSceneTypes, SVSelect, SVUtility; SVSelectImpl: CEDAR PROGRAM IMPORTS SVAssembly, SVScene, SVUtility EXPORTS SVSelect = BEGIN Slice: TYPE = SVSceneTypes.Slice; AssemblyGenerator: TYPE = SVScene.AssemblyGenerator; Scene: TYPE = SVSceneTypes.Scene; SliceDescriptor: TYPE = SVSceneTypes.SliceDescriptor; SliceParts: TYPE = SVSceneTypes.SliceParts; SelectionClass: TYPE = SVSelect.SelectionClass; SliceDescriptorGenerator: TYPE = SVSceneTypes.SliceDescriptorGenerator; SliceDescriptorGeneratorObj: TYPE = SVSceneTypes.SliceDescriptorGeneratorObj; ChangeDonkeyTail: PROC [sliceD: SliceDescriptor, selectClass: SelectionClass] = { SELECT selectClass FROM normal => sliceD.slice.normalSelectedParts _ sliceD; hot => sliceD.slice.hotSelectedParts _ sliceD; active => sliceD.slice.activeSelectedParts _ sliceD; ENDCASE; }; NoDonkeyTail: PROC [slice: Slice, selectClass: SelectionClass] = { SELECT selectClass FROM normal => slice.normalSelectedParts _ NIL; hot => slice.hotSelectedParts _ NIL; active => slice.activeSelectedParts _ NIL; ENDCASE; }; SelectAll: PUBLIC PROC [scene: Scene, selectClass: SelectionClass] = { g: AssemblyGenerator; g _ SVScene.PrimAssembliesInScene[scene]; FOR slice: Slice _ SVScene.NextAssembly[g], SVScene.NextAssembly[g] UNTIL slice = NIL DO SelectEntireSlice[slice, scene, selectClass]; ENDLOOP; }; SelectSlice: PUBLIC PROC [sliceD: SliceDescriptor, scene: Scene, selectClass: SelectionClass] = { oldSliceD, union: SliceDescriptor; slice: Slice _ sliceD.slice; IF SVAssembly.IsEmptyParts[sliceD] THEN RETURN; oldSliceD _ FindSelectedSlice[slice, scene, selectClass]; IF oldSliceD#NIL THEN { union _ SVAssembly.UnionParts[oldSliceD, sliceD]; DeselectSlice[slice, oldSliceD.parts, scene, selectClass]; -- throw away old selection } ELSE union _ sliceD; IF selectClass = normal THEN union _ SVAssembly.AugmentParts[union, selectClass]; AppendSelection[scene, union, selectClass]; ChangeDonkeyTail[union, selectClass]; }; SelectEntireSlice: PUBLIC PROC [slice: Slice, scene: Scene, selectClass: SelectionClass] = { allParts: SliceDescriptor _ SVAssembly.NewParts[slice, NIL, [0,0,0], slice]; SelectSlice[allParts, scene, selectClass]; }; DeselectAll: PUBLIC PROC [scene: Scene, selectClass: SelectionClass] = { sliceD: SliceDescriptor; FOR selected: LIST OF SliceDescriptor _ ListSelected[scene, selectClass], selected.rest UNTIL selected = NIL DO sliceD _ selected.first; NoDonkeyTail[sliceD.slice, selectClass]; ENDLOOP; SetSelectedList[scene, NIL, selectClass]; }; DeselectAllAllClasses: PUBLIC PROC [scene: Scene] = { DeselectAll[scene, normal]; DeselectAll[scene, active]; DeselectAll[scene, hot]; }; DeselectSliceAllClasses: PUBLIC PROC [slice: Slice, scene: Scene] = { DeselectEntireSlice[slice, scene, normal]; DeselectEntireSlice[slice, scene, active]; DeselectEntireSlice[slice, scene, hot]; }; DeselectEntireSlice: PUBLIC PROC [slice: Slice, scene: Scene, selectClass: SelectionClass] = { oldD: SliceDescriptor; oldD _ FindSelectedSlice[slice, scene, selectClass]; IF oldD # NIL THEN { DeleteSelection[scene, oldD, selectClass]; NoDonkeyTail[oldD.slice, selectClass]; }; }; DeselectSlice: PUBLIC PROC [slice: Slice, parts: SliceParts, scene: Scene, selectClass: SelectionClass] = { oldD, newD, tempD: SliceDescriptor; oldD _ FindSelectedSlice[slice, scene, selectClass]; IF oldD # NIL THEN { tempD _ SVAssembly.DescriptorFromParts[slice, parts]; newD _ SVAssembly.DifferenceParts[oldD, tempD]; DeleteSelection[scene, oldD, selectClass]; NoDonkeyTail[oldD.slice, selectClass]; IF NOT SVAssembly.IsEmptyParts[newD] THEN { IF selectClass = normal THEN newD _ SVAssembly.AugmentParts[newD, selectClass]; AppendSelection[scene, newD, selectClass]; ChangeDonkeyTail[newD, selectClass]; }; }; }; DeleteSelection: PROC [scene: Scene, sliceD: SliceDescriptor, selectClass: SelectionClass] = { SetSelectedList[scene, SVUtility.DeleteSliceDescriptorFromList[sliceD, ListSelected[scene, selectClass]], selectClass]; }; ListSelected: PUBLIC PROC [scene: Scene, selectClass: SelectionClass] RETURNS [selectedList: LIST OF SliceDescriptor] = { SELECT selectClass FROM normal => selectedList _ scene.selected.normal; hot => selectedList _ scene.selected.hot; active => selectedList _ scene.selected.active; ENDCASE => ERROR; }; AppendSelection: PROC [scene: Scene, entity: SliceDescriptor, selectClass: SelectionClass] = { SELECT selectClass FROM normal => { IF scene.selected.normal = NIL THEN { scene.selected.normal _ LIST[entity]; scene.selected.normalPtr _ scene.selected.normal; scene.selected.normalPtrValid _ TRUE; } ELSE IF scene.selected.normalPtrValid THEN { scene.selected.normalPtr.rest _ LIST[entity]; scene.selected.normalPtr _ scene.selected.normalPtr.rest; } ELSE { scene.selected.normalPtr _ LastSliceDescriptor[scene.selected.normal]; scene.selected.normalPtr.rest _ LIST[entity]; scene.selected.normalPtr _ scene.selected.normalPtr.rest; scene.selected.normalPtrValid _ TRUE; }; }; hot => { IF scene.selected.hot = NIL THEN { scene.selected.hot _ LIST[entity]; scene.selected.hotPtr _ scene.selected.hot; scene.selected.hotPtrValid _ TRUE; } ELSE IF scene.selected.hotPtrValid THEN { scene.selected.hotPtr.rest _ LIST[entity]; scene.selected.hotPtr _ scene.selected.hotPtr.rest; } ELSE { scene.selected.hotPtr _ LastSliceDescriptor[scene.selected.hot]; scene.selected.hotPtr.rest _ LIST[entity]; scene.selected.hotPtr _ scene.selected.hotPtr.rest; scene.selected.hotPtrValid _ TRUE; }; }; active => { IF scene.selected.active = NIL THEN { scene.selected.active _ LIST[entity]; scene.selected.activePtr _ scene.selected.active; scene.selected.activePtrValid _ TRUE; } ELSE IF scene.selected.activePtrValid THEN { scene.selected.activePtr.rest _ LIST[entity]; scene.selected.activePtr _ scene.selected.activePtr.rest; } ELSE { scene.selected.activePtr _ LastSliceDescriptor[scene.selected.active]; scene.selected.activePtr.rest _ LIST[entity]; scene.selected.activePtr _ scene.selected.activePtr.rest; scene.selected.activePtrValid _ TRUE; }; }; ENDCASE => ERROR; }; LastSliceDescriptor: PROC [sliceDList: LIST OF SliceDescriptor] RETURNS [last: LIST OF SliceDescriptor] = { FOR last _ sliceDList, last.rest UNTIL last.rest = NIL DO ENDLOOP; }; SetSelectedList: PROC [scene: Scene, value: LIST OF SliceDescriptor, selectClass: SelectionClass] = { SELECT selectClass FROM normal => { scene.selected.normal _ value; scene.selected.normalPtrValid _ FALSE; }; hot => { scene.selected.hot _ value; scene.selected.hotPtrValid _ FALSE; }; active => { scene.selected.active _ value; scene.selected.activePtrValid _ FALSE; }; ENDCASE => ERROR; }; IsSelectedInFull: PUBLIC PROC [slice: Slice, scene: Scene, selectClass: SelectionClass] RETURNS [BOOL] = { donkeyTail: SliceDescriptor _ SELECT selectClass FROM active => slice.activeSelectedParts, hot => slice.hotSelectedParts, normal => slice.normalSelectedParts, ENDCASE => ERROR; IF donkeyTail = NIL THEN RETURN[FALSE]; RETURN[SVAssembly.IsCompleteParts[donkeyTail]]; }; IsSelectedInPart: PUBLIC PROC [slice: Slice, scene: Scene, selectClass: SelectionClass] RETURNS [BOOL] = { sliceD: SliceDescriptor; sliceD _ FindSelectedSlice[slice, scene, selectClass]; RETURN[sliceD # NIL]; }; FindSelectedSlice: PUBLIC PROC [slice: Slice, scene: Scene, selectClass: SelectionClass] RETURNS [sliceD: SliceDescriptor] = { SELECT selectClass FROM normal => sliceD _ IF slice.normalSelectedParts = NIL THEN NIL ELSE slice.normalSelectedParts; hot => sliceD _ IF slice.hotSelectedParts = NIL THEN NIL ELSE slice.hotSelectedParts; active => sliceD _ IF slice.activeSelectedParts = NIL THEN NIL ELSE slice.activeSelectedParts; ENDCASE => ERROR; }; SelectedSlices: PUBLIC PROC [scene: Scene, selectClass: SelectionClass] RETURNS [sliceDescGen: SliceDescriptorGenerator] = { sliceD: SliceDescriptor _ NIL; ptr: LIST OF SliceDescriptor _ NIL; sliceDescGen _ NEW[SliceDescriptorGeneratorObj]; FOR entityList: LIST OF SliceDescriptor _ ListSelected[scene, selectClass], entityList.rest UNTIL entityList = NIL DO sliceD _ NARROW[entityList.first]; [sliceDescGen.list, ptr] _ AddSliceDescriptor[sliceD, sliceDescGen.list, ptr]; ENDLOOP; }; AddSliceDescriptor: PROC [entity: SliceDescriptor, entityList, ptr: LIST OF SliceDescriptor] RETURNS [newList, newPtr: LIST OF SliceDescriptor] = { IF ptr = NIL THEN { IF NOT entityList = NIL THEN ERROR; newPtr _ newList _ CONS[entity, NIL]; RETURN; } ELSE { newList _ entityList; ptr.rest _ CONS[entity, NIL]; newPtr _ ptr.rest; }; }; NextSliceDescriptor: PUBLIC PROC [g: SliceDescriptorGenerator] RETURNS [next: SliceDescriptor] = { IF g.list = NIL THEN RETURN[NIL] ELSE { next _ g.list.first; g.list _ g.list.rest; }; }; NextSlice: PUBLIC PROC [g: SliceDescriptorGenerator] RETURNS [next: Slice] = { IF g.list = NIL THEN RETURN[NIL] ELSE { next _ g.list.first.slice; g.list _ g.list.rest; }; }; NoSelections: PUBLIC PROC [scene: Scene, selectClass: SelectionClass] RETURNS [BOOL] = { SELECT selectClass FROM normal => RETURN[scene.selected.normal = NIL]; hot => RETURN[scene.selected.hot = NIL]; active => RETURN[scene.selected.active = NIL]; ENDCASE => ERROR; }; END. €SVSelectImpl.mesa Copyright c 1986 by Xerox Corporation. All rights reserved. Last edited by Bier on March 11, 1987 4:43:56 pm PST Contents: To provide a selection mechanism for Solidviews similar to the one found in Gargoyle. In particular, we maintain a list of the selected objects and offer generators and structure browsers to walk through this list. SliceGenerator: TYPE = SVSceneTypes.SliceGenerator; AppendSelection: PROC [scene: Scene, sliceD: SliceDescriptor, selectClass: SelectionClass] = { Build the selection list in the proper order and keep it that way. SELECT selectClass FROM normal => scene.selected.normal _ NARROW[GList.Nconc[scene.selected.normal, LIST[sliceD]]]; hot => scene.selected.hot _ NARROW[GList.Nconc[scene.selected.hot, LIST[sliceD]]]; active => scene.selected.active _ NARROW[GList.Nconc[scene.selected.active, LIST[sliceD]]]; ENDCASE => ERROR; }; Utilities Deletes entity from list. If it is not on the list, do nothing. OPERATIONS THAT ALTER THE SELECTED LISTS Build the selection list in the proper order and keep it that way. Enumerate Selected Objects Returns TRUE if all or part of entity is selected. These are the cases: 1) entity is a slice. Some outline is selected all or in part. 2) entity is an outline. Some trajectory is selected all or in part. 3) entity is a trajectory. Some joint or segment is selected. 4) entity is a sequence. Some joint or segment is selected. Κ ˜J˜Icodešœ™Kšœ Οmœ1™˜\Kšœ7žœ˜LKšœ*˜*K˜K™—šŸ œžœžœ0˜HKšœ˜š žœ žœžœCžœ žœž˜oKšœ˜Kšœ(˜(Kšžœ˜—Kšœžœ˜)K˜K˜—šŸœžœžœ˜5Kšœ˜Kšœ˜Kšœ˜K˜K˜—šŸœžœžœ!˜EKšœ*˜*Kšœ*˜*Kšœ'˜'K˜K˜—šŸœžœžœ>˜^Kšœ˜Kšœ4˜4šžœžœžœ˜Kšœ*˜*Kšœ&˜&K˜—K˜K˜—šŸ œžœžœQ˜kKšœ#˜#Kšœ4˜4šžœžœžœ˜Kšœ5˜5Kšœ/˜/Kšœ*˜*Kšœ&˜&šžœžœžœ˜+Kšžœžœ3˜OKšœ*˜*Kšœ$˜$K˜—K˜—K˜—šŸœžœI™^K™Bšžœ ž™Kšœ"žœ$žœ ™[Kšœžœ!žœ ™RKšœ"žœ$žœ ™[Kšžœžœ™—K™K™—K™K™ šŸœžœI˜^K™@šœ˜KšœR˜RKšœ ˜ —K˜K˜—š Ÿ œžœžœ-žœžœžœ˜yšžœ ž˜Kšœ/˜/Kšœ)˜)Kšœ/˜/Kšžœžœ˜—K˜K˜—K™K™(K™šŸœžœI˜^K™Bšžœ ž˜šœ ˜ šžœžœžœ˜%Kšœžœ ˜%Kšœ1˜1Kšœ žœ˜%K˜—šžœžœžœ˜,Kšœ žœ ˜-Kšœ9˜9K˜—šžœ˜KšœF˜FKšœ žœ ˜-Kšœ9˜9Kšœ žœ˜%K˜—K˜—šœ˜šžœžœžœ˜"Kšœžœ ˜"Kšœ+˜+Kšœžœ˜"K˜—šžœžœžœ˜)Kšœžœ ˜*Kšœ3˜3K˜—šžœ˜Kšœ@˜@Kšœžœ ˜*Kšœ3˜3Kšœžœ˜"K˜—K˜—šœ ˜ šžœžœžœ˜%Kšœžœ ˜%Kšœ1˜1Kšœ žœ˜%K˜—šžœžœžœ˜,Kšœ žœ ˜-Kšœ9˜9K˜—šžœ˜KšœF˜FKšœ žœ ˜-Kšœ9˜9Kšœ žœ˜%K˜—K˜—Kšžœžœ˜—K˜K˜—šŸœžœžœžœžœžœžœ˜kKš žœžœ žœžœžœ˜BK˜K˜—šŸœžœžœžœ2˜ešžœ ž˜šœ ˜ Kšœ˜Kšœ žœ˜&K˜—šœ˜Kšœ˜Kšœžœ˜#K˜—šœ ˜ Kšœ˜Kšœ žœ˜&K˜—Kšžœžœ˜—K˜—K˜K™š Ÿœžœžœ;žœžœ˜jšœžœ ž˜5Kšœ$˜$Kšœ˜Kšœ$˜$Kšžœžœ˜—Kš žœžœžœžœžœ˜'Kšžœ)˜/K˜K˜—š Ÿœžœžœ;žœžœ˜jKšœH™HKšœ@™@KšœF™FKšœ?™?Kšœ=™=K˜Kšœ6˜6Kšžœ žœ˜K˜K™—šŸœžœžœ;žœ˜~šžœ ž˜Kš œžœžœžœžœžœ˜^Kš œžœžœžœžœžœ˜UKš œžœžœžœžœžœ˜^Kšžœžœ˜—Kšœ˜K˜—šŸœžœžœ-žœ-˜|Kšœžœ˜Kšœžœžœžœ˜#Kšœžœ˜0š žœ žœžœEžœžœž˜uKšœ žœ˜"KšœN˜NKšžœ˜—K˜K˜—šŸœžœ,žœžœžœžœžœ˜“šžœžœžœ˜Kš žœžœžœžœžœ˜#Kšœžœ žœ˜%Kšžœ˜K˜—šžœ˜Kšœ˜Kšœ žœ žœ˜Kšœ˜K˜—K˜K˜—šŸœž œžœ˜bKš žœ žœžœžœžœ˜ šžœ˜Kšœ˜K˜K˜—Kšœ˜K˜—šŸ œž œžœ˜NKš žœ žœžœžœžœ˜ šžœ˜Kšœ˜K˜K˜—Kšœ˜K˜K˜—š Ÿ œžœžœ-žœžœ˜Xšžœ ž˜Kšœ žœžœ˜.Kšœžœžœ˜(Kšœ žœžœ˜.Kšžœžœ˜—K˜K˜—K˜Kšžœ˜K˜J˜—…—#€4e