CombinePolyImpl.mesa
Copyright © 1986 by Xerox Corporation. All rights reserved.
Last edited by Arnon on February 14, 1986 12:07:11 pm PST
DIRECTORY
Imager,
RatNums,
EuclideanGraphs,
ConvexEuclideanGraphs,
ConvexCombiner,
CombinePoly;
CombinePolyImpl: CEDAR PROGRAM
IMPORTS EuclideanGraphs, ConvexEuclideanGraphs, ConvexCombiner
EXPORTS CombinePoly
= BEGIN OPEN RN: RatNums, EG: EuclideanGraphs, CEG: ConvexEuclideanGraphs, CC: ConvexCombiner, CombinePoly;
PointList: TYPE = LIST OF Point; -- Used to reverse order of points on Imager.Trajectory, and omit last (repeats first) point.
PointGeneratorObj: PUBLIC TYPE = RECORD [
points: PointList
];
RegionGeneratorObj: PUBLIC TYPE = RECORD [
regions: CEG.RegionList
];
CreatePolygon: PUBLIC PROC [point1, point2: Point, clientData: REF] RETURNS [polyID: PolyID] ~ {
ratPoint1: EG.Point ← EG.MakePointFromReals[point1[1], point1[2]];
ratPoint2: EG.Point ← EG.MakePointFromReals[point2[1], point2[2]];
entryPrior, entryNext: EG.Vertex ← NIL;
[entryPrior, entryNext] ← CEG.AddVertexToPolygon [entryPrior, entryNext, ratPoint1, clientData];
[entryPrior, entryNext] ← CEG.AddVertexToPolygon [entryPrior, entryNext, ratPoint2, clientData];
RETURN[entryNext];
};
AddPointToPolygon: PUBLIC PROC [point: Point, polyid: PolyID] ~ {
ratPoint: EG.Point ← EG.MakePointFromReals[point[1], point[2]];
entryNext: EG.Vertex ← polyid;
entryPrior: EG.Vertex ← CEG.SpecialPreviousOutlineVertex[entryNext];
thisToNext, nextToThis: EG.Adjacency;
exitPrior: EG.Vertex;
clientData: REF;
IF polyid=NIL OR polyid.adjacentVertices=NIL THEN ERROR; -- AddPointToPolygon can only be called on a polygon that already has at least two vertices;
[thisToNext, nextToThis] ← EG.FindAdjacency[entryPrior, entryNext];
clientData ← CEG.GetEdgeClientData[thisToNext];
[exitPrior, entryNext] ← CEG.AddVertexToPolygon[entryPrior, entryNext, ratPoint, clientData];
RETURN;
};
PolygonIntoDatabase: PUBLIC PROC [polyID: PolyID, dbid: DBID, overlapHandler: RegionOverlapProc, glueHandler: RegionGlueProc] RETURNS[newDbid: DBID] ~ {
startToEnd, endToStart: EG.Adjacency;
inputClientData: REF;
previous: EG.Vertex ← CEG.SpecialPreviousOutlineVertex[polyID];
[startToEnd, endToStart] ← EG.FindAdjacency[previous, polyID];
inputClientData ← CEG.GetEdgeClientData[startToEnd];
newDbid ← CC.Combiner[dbid, polyID, inputClientData, overlapHandler];
CC.SimpleCleaner[newDbid, glueHandler]; -- currently disabled
};
MaximalRegions: PUBLIC PROC [dbid: DBID, isA: IsAProc] RETURNS [regionGen: RegionGenerator] ~ {
regionGen ← NEW[RegionGeneratorObj ← [regions: CEG.MaximalRegions[dbid, isA] ] ];
RETURN[regionGen];
};
TrajectoryToPointList: PROC [traj: Imager.Trajectory] RETURNS [list: PointList ← NIL] ~ {
point: Point;
WHILE traj.prev#NIL DO -- omit last point
point[1] ← traj.lp.x; point[2] ← traj.lp.y;
list ← CONS[point, list]; traj ← traj.prev;
ENDLOOP;
};
NextPoint: PUBLIC PROC [pointGen: PointGenerator] RETURNS [pointAndDone: PointAndDone] ~ {
IF pointGen.points = NIL THEN ERROR
ELSE {
nextPoint: Point ← pointGen.points.first;
pointGen.points ← pointGen.points.rest;
RETURN[NEW[PointAndDoneRec ← [
point: nextPoint,
done: pointGen.points = NIL
] ] ];
};
};
NextRegion: PUBLIC PROC [regionGen: RegionGenerator] RETURNS [outlineHolesDataAndDone: OutlineHolesDataAndDone] ~ {
IF regionGen.regions = NIL THEN ERROR
ELSE {
nextRegion: CEG.Region ← regionGen.regions.first;
regionGen.regions ← regionGen.regions.rest;
RETURN[NEW[OutlineHolesDataAndDoneRec ← [
outline: NEW[PointGeneratorObj ← [points: TrajectoryToPointList[nextRegion.outline] ] ],
holes: (IF nextRegion.holes=NIL THEN NIL ELSE NEW[RegionGeneratorObj ← [regions: nextRegion.holes] ] ),
data: nextRegion.clientData,
done: regionGen.regions = NIL
] ] ];
};
};
END.