CleanObjectsImpl.mesa
Last Edited by: Gbier, July 11, 1985 12:181:45 pm PDT
Last Edited by: Gbier, July 26, 1985 10:56:06 am PDT
Jacobi, September 24, 1985 10:07:42 am PDT
DIRECTORY
CD,
CDBasics,
CornerStitching,
CDOrient,
CDCells,
CDRects,
CDMenus,
CDSequencer,
CDInstances,
CDProperties,
CDDirectory,
Recognizer,
TerminalIO,
CleanObjects;
CleanObjectsImpl:
CEDAR
PROGRAM
IMPORTS CD, CDBasics, CornerStitching, CDOrient, CDCells, CDInstances, CDProperties, CDDirectory, CDRects, CDMenus, CDSequencer, Recognizer, TerminalIO
EXPORTS CleanObjects =
BEGIN
LayerAndTessPtr: TYPE = REF LayerAndTessRec;
LayerAndTessRec:
TYPE =
RECORD [
design: CD.Design,
cellOb: CD.Object,
cellPtr: CD.CellPtr,
abstract: CD.Layer ← CD.combined,
actual: CD.Layer ← CD.combined,
surround: CD.Layer ← CD.combined,
surroundExt: CD.Number ← 0,
actualPlane: REF CornerStitching.Tesselation ← NIL,
surroundPlane: REF CornerStitching.Tesselation ← NIL,
instance: CD.Instance ← NIL
];
AbstractLayerRec:
TYPE =
RECORD [
technology: CD.Technology,
abstract: CD.Layer,
actual: CD.Layer,
surround: CD.Layer, --The surrounding layer of an abstract layer
surroundExt: CD.Number --The extension of the surrounding layer
];
abstractLayerList: LIST OF REF AbstractLayerRec ← NIL; --contains registered abstract Layers
RegionList: TYPE = LIST OF REF CornerStitching.Region;
CleanObjects:
PUBLIC
PROC [cellOb:
CD.Object, design:
CD.Design, recognizeObjects:
BOOL ←
TRUE] =
BEGIN
WITH cellOb.specificRef
SELECT
FROM
cp:
CD.CellPtr => {
IF recognizeObjects THEN Recognizer.RecognizeObjects[design, cellOb];
CleanCell[design, cellOb];
[] ← CDCells.RepositionCell[cellOb, design];
CDDirectory.PropagateChange[cellOb, design];
};
ENDCASE => NULL;
END;
CleanObjectsAllLevels:
PROC [design:
CD.Design, recognizeObjects:
BOOL] =
BEGIN
DoIt: CDDirectory.EachEntryAction = {
CleanObjects[cellOb: ob, design: design, recognizeObjects: recognizeObjects]
};
[] ← CDDirectory.Enumerate[design, DoIt];
CleanObjects[design.actual.first.dummyCell.ob, design, recognizeObjects];
END;
RecognizeAllCommand:
PROC [comm: CDSequencer.Command] =
BEGIN
TerminalIO.WriteRope["Recognize on all levels\n"];
CleanObjectsAllLevels[design: comm.design, recognizeObjects: TRUE];
TerminalIO.WriteRope["Recognizer and Cleaning Done\n"];
END;
RecognizeTopCommand:
PROC [comm: CDSequencer.Command] =
BEGIN
TerminalIO.WriteRope["Recognize on top level\n"];
CleanObjects[comm.design.actual.first.dummyCell.ob, comm.design, TRUE];
TerminalIO.WriteRope["Recognizer and Cleaning Done\n"];
END;
CleanCell:
PROC [design:
CD.Design, cellOb:
CD.Object] =
BEGIN
passTessInfo: LayerAndTessPtr ← NEW[LayerAndTessRec ← [design, cellOb, NARROW[cellOb.specificRef]]];
FOR layerList:
LIST
OF
CD.Layer ← design.technology.usedLayers, layerList.rest
WHILE layerList #
NIL
DO
passTessInfo.abstract ← layerList.first;
passTessInfo.actual ← layerList.first;
passTessInfo.surround ← CD.combined;
FOR abstractList:
LIST
OF
REF AbstractLayerRec ← abstractLayerList, abstractList.rest
WHILE abstractList #
NIL
DO
IF abstractList.first.technology = design.technology
AND abstractList.first.abstract = passTessInfo.abstract
THEN {
passTessInfo.actual ← abstractList.first.actual;
passTessInfo.surround ← abstractList.first.surround;
passTessInfo.surroundExt ← abstractList.first.surroundExt;
EXIT;
}
ENDLOOP;
passTessInfo.actualPlane ← CornerStitching.NewTesselation[];
passTessInfo.surroundPlane ← CornerStitching.NewTesselation[];
FillPlanesByDrawingObjects[passTessInfo];
CheckRectsAgainstPlane[passTessInfo];
ENDLOOP;
END;
FillPlanesByDrawingObjects:
PROC [passTessInfo: LayerAndTessPtr] =
BEGIN
pr: CD.DrawRef ← CD.CreateDrawRef[passTessInfo.design];
pr.devicePrivate ← passTessInfo;
pr.drawRect ← DrawObjectsIntoPlanes;
FOR instanceList:
CD.InstanceList ← passTessInfo.cellPtr.contents, instanceList.rest
WHILE instanceList #
NIL
DO
IF ~instanceList.first.ob.class.wireTyped
AND FlattenObject[instance: instanceList.first]
THEN
instanceList.first.ob.class.drawMe[inst: instanceList.first, pos: instanceList.first.location, orient: instanceList.first.orientation, pr: pr];
ENDLOOP;
END;
FlattenObject:
PROC [instance:
CD.Instance]
RETURNS [
BOOL ←
TRUE] =
BEGIN
IF instance.ob.class.inDirectory THEN RETURN[FALSE];
END;
DrawObjectsIntoPlanes:
PROC [r:
CD.Rect, l:
CD.Layer, pr:
CD.DrawRef] =
BEGIN
passTessInfo: LayerAndTessPtr ← NARROW[pr.devicePrivate];
IF passTessInfo.actual = l
THEN
CornerStitching.ChangeRect [plane: passTessInfo.actualPlane, rect: r, newValue: $cover]
ELSE
IF passTessInfo.surround = l
THEN
CornerStitching.ChangeRect[plane: passTessInfo.surroundPlane, rect: r, newValue: $cover];
END;
CheckRectsAgainstPlane:
PROC [passTessInfo: LayerAndTessPtr] =
BEGIN
FOR instanceList:
CD.InstanceList ← passTessInfo.cellPtr.contents, instanceList.rest
WHILE instanceList#
NIL
DO
IF instanceList.first.ob.class.wireTyped
AND instanceList.first.ob.layer = passTessInfo.abstract
AND WireNeededCleaning [instanceList.first, passTessInfo]
THEN
[] ← CDCells.RemoveInstance[design: passTessInfo.design, cell: passTessInfo.cellOb, inst: instanceList.first];
ENDLOOP;
END;
WireNeededCleaning:
PROC [instance:
CD.Instance, passTessInfo: LayerAndTessPtr]
RETURNS [addedWire:
BOOL ←
FALSE] =
BEGIN
rect: CD.Rect ← CDInstances.InstRectI[instance];
keepList: RegionList ← NARROW[CornerStitching.EnumerateArea [plane: passTessInfo.actualPlane, rect: rect, backgroundValue: $cover]];
throwAwayList: RegionList ← NARROW[CornerStitching.EnumerateArea [plane: passTessInfo.actualPlane, rect: rect]];
IF passTessInfo.surround #
CD.combined
THEN
--current Layer is an abstract Layer
keepList ← UncoveredSurroundPieces[keepList, throwAwayList, passTessInfo.surroundPlane, passTessInfo.surroundExt];
keepList ← BuildKeepList[keepList, instance, rect];
IF keepList = NIL THEN RETURN[TRUE];
IF (keepList.first.value = NIL) AND (keepList.first.rect = rect) AND (keepList.rest = NIL) THEN RETURN; --keep whole wire
WHILE keepList #
NIL
DO {
location: CD.Position ← CDBasics.BaseOfRect [keepList.first.rect];
object: CD.Object ← CDRects.CreateRect[CDOrient.OrientedSize[CDBasics.SizeOfRect[keepList.first.rect], instance.orientation], passTessInfo.abstract];
newInst:
CD.Instance ← CDCells.IncludeOb[
design: passTessInfo.design,
cell: passTessInfo.cellOb,
ob: object,
position: location,
orientation: instance.orientation,
cellCSystem: cdCoords,
obCSystem: interrestCoords,
mode: dontPropagate
].newInst;
CDProperties.CopyProps[instance.properties, newInst];
addedWire ← TRUE;
};
keepList ← keepList.rest;
ENDLOOP;
END;
BuildKeepList:
PROC [keepList: RegionList, instance:
CD.Instance, rect:
CD.Rect]
RETURNS [newKeepList: RegionList] =
--If a piece on the keeplist is actually a cut along the width then the piece is grown to the full width of the original wire.
BEGIN
xWidth: BOOL;
width: CD.Number;
length: CD.Number;
changed: BOOL ← TRUE;
wirePlane: REF CornerStitching.Tesselation ← CornerStitching.NewTesselation[];
WHILE keepList #
NIL
DO
CornerStitching.ChangeRect[plane: wirePlane, rect: keepList.first.rect, newValue: $cover];
keepList ← keepList.rest;
ENDLOOP;
IF CDOrient.IncludesOddRot90[instance.orientation]
THEN {
xWidth ← FALSE;
width ← rect.y2-rect.y1;
length ← rect.x2-rect.x1;
}
ELSE {
xWidth ← TRUE;
width ← rect.x2-rect.x1;
length ← rect.y2-rect.y1;
};
IF length > width
THEN
-- normal shaped object
WHILE changed
DO
changed ← FALSE;
newKeepList ← NARROW[CornerStitching.EnumerateArea[plane: wirePlane, rect: rect]];
WHILE newKeepList #
NIL
DO
IF xWidth
AND (newKeepList.first.rect.x2-newKeepList.first.rect.x1) #width
THEN {
changed ← TRUE;
CornerStitching.ChangeRect[plane: wirePlane, rect: [rect.x1, newKeepList.first.rect.y1, rect.x2, newKeepList.first.rect.y2], newValue: $cover];
};
IF ~xWidth
AND (newKeepList.first.rect.y2-newKeepList.first.rect.y1) #width
THEN {
changed ← TRUE;
CornerStitching.ChangeRect[plane: wirePlane, rect: [newKeepList.first.rect.x1, rect.y1, newKeepList.first.rect.x2, rect.y2], newValue: $cover];
};
newKeepList ← newKeepList.rest;
ENDLOOP;
ENDLOOP;
RETURN[newKeepList ← NARROW[CornerStitching.EnumerateArea[plane: wirePlane, rect: rect]]];
END;
UncoveredSurroundPieces:
PROC [keepList, throwAwayList: RegionList, surroundPlane:
REF CornerStitching.Tesselation, surroundExt:
CD.Number]
RETURNS [newKeepList: RegionList] =
--Used for verifying abstract layers. All pieces on throwAwayList must be surrounded, otherwise the piece is moved onto the keepList
BEGIN
newKeepList ← keepList;
WHILE keepList #
NIL
DO
CornerStitching.ChangeRect[plane: surroundPlane, rect: CDBasics.Extend[keepList.first.rect, surroundExt], newValue: $cover];
keepList ← keepList.rest;
ENDLOOP;
WHILE throwAwayList #
NIL
DO
IF ~RectCoveredCompletely[throwAwayList.first.rect, surroundPlane, surroundExt]
THEN
newKeepList ← CONS[throwAwayList.first, newKeepList];
throwAwayList ← throwAwayList.rest;
ENDLOOP;
END;
RectCoveredCompletely:
PROC [rect:
CD.Rect, plane:
REF CornerStitching.Tesselation, surroundExt:
CD.Number]
RETURNS [
BOOL ←
TRUE] =
BEGIN
FOR surroundList: RegionList ←
NARROW[CornerStitching.EnumerateArea[plane: plane, rect: CDBasics.Extend[rect, surroundExt], backgroundValue: $none]], surroundList.rest
WHILE surroundList #
NIL
DO
IF surroundList.first.value =
NIL
THEN
RETURN[FALSE];
ENDLOOP;
END;
RegisterAbstractLayer:
PUBLIC
PROC [technology:
CD.Technology, abstract, actual, surround:
CD.Layer, surroundExt:
CD.Number] =
BEGIN
abstractLayerList ← CONS[NEW[AbstractLayerRec ← [technology, abstract, actual, surround, surroundExt]], abstractLayerList];
END;
CDMenus.CreateEntry[menu: $ProgramMenu, entry: "Recognize All", key: $RecognizeAll];
CDMenus.CreateEntry[menu: $ProgramMenu, entry: "Recognize Top", key: $RecognizeTop];
CDSequencer.ImplementCommand[a: $RecognizeAll, p: RecognizeAllCommand, queue: doQueue];
CDSequencer.ImplementCommand[a: $RecognizeTop, p: RecognizeTopCommand, queue: doQueue];
END.