SimpleCombinerImpl.mesa
Last Edited by: Arnon, June 20, 1985 4:44:33 pm PDT
DIRECTORY
ClientStateInfo USING [defaultState, StateCombiner, State],
Imager USING [VEC],
RatNums USING [RatNumFromREAL],
RCombiner USING [Combiner],
RVHandleUtils USING [AddVertexToPolygon, ImagerPolygonAndStateList, PreviousOutlineVertex, PolygonExtractor, ClearVisitedFields],
SimpleCombiner;
SimpleCombinerImpl: CEDAR PROGRAM
IMPORTS ClientStateInfo, RCombiner, RVHandleUtils, RatNums
EXPORTS SimpleCombiner =
BEGIN OPEN CSI: ClientStateInfo, RVHU: RVHandleUtils, RCB: RCombiner, RN: RatNums, SimpleCombiner;
PrivateState: TYPE = REF InclusionRelation;
InclusionRelation: TYPE = { inside }; -- our model is that retained areas have state "inside", and unretained areas have state NIL
Combiner: PUBLIC PROC [ convexPolygon: Outline, stateCombineRule: BooleanFunction, currentStructure: CombinerStructure ← NIL] RETURNS [ CombinerStructure ] = {
lowerStructure, upperStructure: CombinerStructure;
SELECT stateCombineRule FROM
Union => {
upperStructure ← OutlineToVHandle[ convexPolygon ];
lowerStructure ← RCB.Combiner[currentStructure, upperStructure, CSI.defaultState, Union ];
};
Difference => {
upperStructure ← OutlineToVHandle[ convexPolygon, NIL ];
lowerStructure ← RCB.Combiner[currentStructure, upperStructure, NIL, Difference ];
};
ENDCASE => ERROR;
RETURN[ lowerStructure ];
};
OutlineToVHandle: PROC [T: Outline, state: CSI.State ← CSI.defaultState] RETURNS [v: CombinerStructure] ~ {
L: LIST OF Imager.VECNIL;
WHILE T.prev # NIL DO
L ← CONS[T.lp, L];
T ← T.prev;
ENDLOOP;
v ← NIL;
WHILE L#NIL DO
v ← RVHU.AddVertexToPolygon[v, RN.RatNumFromREAL[L.first.x], RN.RatNumFromREAL[L.first.y], state ];
L ← L.rest;
ENDLOOP;
};
Union: CSI.StateCombiner ~ {
state1: PrivateState ← NARROW[currentregionstate];
state2: PrivateState ← NARROW[inputregionstate];
IF currentregionstate=NIL THEN RETURN[ inputregionstate ];
IF inputregionstate=NIL THEN RETURN[ currentregionstate ];
RETURN[NEW[InclusionRelation ← inside]];
};
Difference: CSI.StateCombiner ~ {
RETURN[ NIL ]; -- StateCombiner is called only where input polygon overlaps current figure, and we know we want to delete such areas.
};
OutlinesFromCombinerStructure: PUBLIC PROC [w: CombinerStructure] RETURNS [LIST OF Outline]={
v: CombinerStructure;
L: RVHU.ImagerPolygonAndStateList;
M: LIST OF Outline ← NIL;
IF w=NIL THEN RETURN[NIL];
v ← RVHU.PreviousOutlineVertex[w];
L ← RVHU.PolygonExtractor[ v, w ];
RVHU.ClearVisitedFields[v, w];
WHILE L#NIL DO
IF L.first.state#NIL THEN M ← CONS[ L.first.trajectory, M];
L ← L.rest;
ENDLOOP;
RETURN[ M ];
};
END.