SVAlignImpl.mesa
Copyright © 1986 by Xerox Corporation. All rights reserved.
Last edited by Bier on March 11, 1987 4:59:39 pm PST
Contents: Maintains the three snap-dragging gravity bags: triggerBag, sceneBag, and alignBag for Solidviews.
DIRECTORY
GList, Process, SVAlign, SVAssembly, SVInterfaceTypes, SVScene, SVSceneTypes, SVSelect;
SVAlignImpl: CEDAR PROGRAM
IMPORTS GList, Process, SVAssembly, SVScene, SVSelect
EXPORTS SVAlign
=
BEGIN
AlignBag: TYPE = SVInterfaceTypes.AlignBag;
Slice: TYPE = SVSceneTypes.Slice;
FeatureData: TYPE = SVInterfaceTypes.FeatureData;
FeatureDataObj: TYPE = SVInterfaceTypes.FeatureDataObj;
FilterSliceProc: TYPE = SVAlign.FilterSliceProc;
Scene: TYPE = SVSceneTypes.Scene;
SliceDescriptor: TYPE = SVSceneTypes.SliceDescriptor;
SliceParts: TYPE = SVSceneTypes.SliceParts;
TriggerBag: TYPE = REF TriggerBagObj;
TriggerBagObj: TYPE = SVInterfaceTypes.TriggerBagObj;
SVData: TYPE = SVInterfaceTypes.SVData;
Creating a TriggerBag
emptyTriggerBag: PUBLIC TriggerBag;
emptyAlignBag: PUBLIC AlignBag;
Use this as an (immutable) empty TriggerBag.
CreateTriggerBag: PUBLIC PROC [scene: Scene] RETURNS [triggerBag: TriggerBag] = {
triggerBag ← NEW[TriggerBagObj ← [tree: scene.tree, scene: scene, slices: NIL, anchor: NIL]];
};
FlushTriggerBag: PUBLIC PROC [triggerBag: TriggerBag] = {
triggerBag.slices ← NIL;
triggerBag.anchor ← NIL;
};
CopyTriggerBag: PUBLIC PROC [triggerBag: TriggerBag] RETURNS [copy: TriggerBag] = {
copy ← CreateTriggerBag[triggerBag.scene];
copy.slices ← NARROW[GList.Copy[triggerBag.slices]];
copy.anchor ← triggerBag.anchor;
};
Filling the SceneBag
FillStaticSceneBag: PUBLIC PROC [scene: Scene, sceneBag: TriggerBag] = {
sceneBag.tree ← scene.tree;
sceneBag.scene ← scene;
AddAllAssemblies[scene, sceneBag];
};
FillDynamicSceneBag: PUBLIC PROC [scene: Scene, sceneBag: TriggerBag] = {
};
Filling all of the Bags at Once
SetStaticBags: PUBLIC PROC [svData: SVData] = {
sceneBag: TriggerBag ← svData.hitTest.sceneBag;
FlushTriggerBag[sceneBag];
FillStaticSceneBag[svData.scene, sceneBag];
};
SetDynamicBags: PUBLIC PROC [svData: SVData, action: ATOM] = {
};
StaticToDynamicBags: PUBLIC PROC [svData: SVData] RETURNS [repaintForeground: BOOL] = {
We are about to drag things around. Here is what that means for each of the bags:
triggerBag: AddHeuristics may add some things. RemoveMoving is going to remove some things.
sceneBag: RemoveMoving is going to remove some things.
alignBag: Those things that RemoveMoving now removes will no longer trigger midpoints, nor alignment lines.
repaintForeground is TRUE if alignBag is altered.
sceneBag: TriggerBag ← svData.hitTest.sceneBag;
Incrementally Update SceneBag
svData.hitTest.oldSceneBag ← sceneBag;
sceneBag ← StaticToDynamicSceneBag[svData.scene, sceneBag];
svData.hitTest.sceneBag ← sceneBag;
};
StaticToDynamicSceneBag: PROC [scene: Scene, sceneBag: TriggerBag] RETURNS [newBag: TriggerBag] = {
newBag ← CopyTriggerBag[sceneBag];
RemoveMoving[scene, newBag];
ComputeAllBoundingBoxes[newBag];
};
DynamicToStaticBags: PUBLIC PROC [svData: SVData] RETURNS [repaintForeground: BOOL] = {
sceneBag: TriggerBag;
sceneBag ← svData.hitTest.sceneBag ← svData.hitTest.oldSceneBag;
};
UpdateBagsForNewSlices: PUBLIC PROC [newSlices: LIST OF Slice, svData: SVData] = {
SetStaticBags[svData];
};
In support of building sceneBag.
AddAllAssemblies: PROC [scene: Scene, triggerBag: TriggerBag] = {
primList: LIST OF Slice ← SVScene.ListOfPrimAssemblies[scene.assembly, scene];
feature: FeatureData;
FOR list: LIST OF Slice ← primList, list.rest UNTIL list = NIL DO
feature ← FeatureFromSlice[list.first];
AddFeature[feature, triggerBag];
ENDLOOP;
};
FeatureFromSlice: PUBLIC PROC [slice: Slice, parts: SliceParts ← NIL] RETURNS [feature: FeatureData] = {
sliceParts: SliceParts ← IF parts=NIL THEN SVAssembly.NewParts[slice, NIL, [0,0,0], slice].parts ELSE parts;
sliceD: SliceDescriptor ← SVAssembly.DescriptorFromParts[slice, sliceParts];
feature ← NEW[FeatureDataObj];
feature.type ← slice;
feature.shape ← sliceD;
};
AddFeature: PROC [featureData: FeatureData, triggerBag: TriggerBag] = {
Process.CheckForAbort[];
SELECT featureData.type FROM
slice => {
triggerBag.slices ← CONS[featureData, triggerBag.slices];
};
anchor => {
triggerBag.anchor ← featureData;
};
ENDCASE => ERROR;
};
The Filter Routines shown in the figure as boxes and ovals
RemoveMoving: PROC [scene: Scene, triggerBag: TriggerBag] = {
If we are about to drag all of the selected objects, then we must remove selected objects from the triggerBag. We must also remove segments which are adjacent to a moving joint (called "dangling" segments), and segments whose control points are selected.
DeleteTriggersFilter[triggerBag, scene, RemoveMovingSlice];
};
RemoveMovingSlice: PROC [sliceD: SliceDescriptor, scene: Scene] RETURNS [stationary: SliceDescriptor] = {
selSliceD: SliceDescriptor ← SVSelect.FindSelectedSlice[sliceD.slice, scene, normal];
background, overlay, rubber, drag, move: SliceDescriptor;
IF selSliceD = NIL THEN RETURN[sliceD]; -- clearly nothing is moving
[background, overlay, rubber, drag] ← SVAssembly.MovingParts[selSliceD.slice, selSliceD.parts];
move ← SVAssembly.UnionParts[rubber, drag];
stationary ← SVAssembly.DifferenceParts[sliceD, move];
};
DeleteTriggersFilter: PROC [triggerBag: TriggerBag, scene: Scene, filterSliceProc: FilterSliceProc] = {
When this procedure is called, all sequences in triggerBag are passed to filterSeqProc. filterSeqProc should return those parts which should be included in the new bag.
sliceD, newSliceD: SliceDescriptor;
sliceFeatures: LIST OF FeatureData ← triggerBag.slices;
newFeature: FeatureData;
triggerBag.slices ← NIL;
FOR sliceList: LIST OF FeatureData ← sliceFeatures, sliceList.rest UNTIL sliceList = NIL DO
sliceD ← NARROW[sliceList.first.shape];
newSliceD ← filterSliceProc[sliceD, scene];
IF NOT SVAssembly.EmptyParts[sliceD] THEN {
newFeature ← FeatureFromSlice[newSliceD.slice, newSliceD.parts];
triggerBag.slices ← CONS[newFeature, triggerBag.slices];
};
ENDLOOP;
};
Init: PROC [] = {
emptyTriggerBag ← NIL;
emptyAlignBag ← NIL;
};
Init[];
END.