DIRECTORY Atom, CD, CDBasics, CDMEBES, CStitching, IO; CDMEBESGeomFns: CEDAR PROGRAM IMPORTS Atom, CDBasics, CDMEBES, CStitching, IO = BEGIN OPEN CDMEBES; Direction: TYPE = {N, E, S, W} _ N; reverseDirection: ARRAY Direction OF Direction _ [N: S, E: W, S: N, W: E]; Juxtaposition: PROC [ a, b: TadRect ] RETURNS [ aVsB: Direction _ N, biggestGap: Tad _ -1 ] = { tGap: Tad; IF (tGap _ b.x1-a.x2) > biggestGap THEN {aVsB _ W; biggestGap _ tGap}; IF (tGap _ a.x1-b.x2) > biggestGap THEN {aVsB _ E; biggestGap _ tGap}; IF (tGap _ b.y1-a.y2) > biggestGap THEN {aVsB _ S; biggestGap _ tGap}; IF (tGap _ a.y1-b.y2) > biggestGap THEN {aVsB _ N; biggestGap _ tGap}; }; ScanNeighborhood: PROC [ proc: PROC [z1, z2, depth: Tad], mother: CStitching.Tile, p1, p2: TadPair, depthLimit: Tad, continueValue: REF _ NIL ] = { InnerDepthScanS: PROC [ tile: CStitching.Tile, z1, z2: Tad ] = { curDepth: Tad = p1.y - tile.NEdge; IF curDepth >= depthLimit THEN proc[z1, z2, depthLimit] ELSE { FOR tileSouth: CStitching.Tile _ tile.WS, tileSouth.NE WHILE tileSouth.WEdge < z2 DO IF tileSouth.EEdge > z1 THEN { IF (curDepth > 0) AND (tileSouth.value # continueValue) THEN proc[z1, z2, curDepth] ELSE InnerDepthScanS[tileSouth, MAX[z1, tileSouth.WEdge], MIN[z2, tileSouth.EEdge]]; }; ENDLOOP; }; }; InnerDepthScanN: PROC [ tile: CStitching.Tile, z1, z2: Tad ] = { curDepth: Tad = tile.SEdge - p1.y; IF curDepth >= depthLimit THEN proc[z1, z2, depthLimit] ELSE { FOR tileNorth: CStitching.Tile _ tile.EN, tileNorth.SW WHILE tileNorth.EEdge > z1 DO IF tileNorth.WEdge < z2 THEN { IF (curDepth > 0) AND (tileNorth.value # continueValue) THEN proc[z1, z2, curDepth] ELSE InnerDepthScanN[tileNorth, MAX[z1, tileNorth.WEdge], MIN[z2, tileNorth.EEdge]]; }; ENDLOOP; }; }; InnerDepthScanE: PROC [ tile: CStitching.Tile, z1, z2: Tad ] = { curDepth: Tad = tile.WEdge - p1.x; IF curDepth >= depthLimit THEN proc[z1, z2, depthLimit] ELSE { FOR tileEast: CStitching.Tile _ tile.NE, tileEast.WS WHILE tileEast.NEdge > z1 DO IF tileEast.SEdge < z2 THEN { IF (curDepth > 0) AND (tileEast.value # continueValue) THEN proc[z1, z2, curDepth] ELSE InnerDepthScanE[tileEast, MAX[z1, tileEast.SEdge], MIN[z2, tileEast.NEdge]]; }; ENDLOOP; }; }; InnerDepthScanW: PROC [ tile: CStitching.Tile, z1, z2: Tad ] = { curDepth: Tad = p1.x - tile.EEdge; IF curDepth >= depthLimit THEN proc[z1, z2, depthLimit] ELSE { FOR tileWest: CStitching.Tile _ tile.SW, tileWest.EN WHILE tileWest.SEdge < z2 DO IF tileWest.NEdge > z1 THEN { IF (curDepth > 0) AND (tileWest.value # continueValue) THEN proc[z1, z2, curDepth] ELSE InnerDepthScanW[tileWest, MAX[z1, tileWest.SEdge], MIN[z2, tileWest.NEdge]]; }; ENDLOOP; }; }; SELECT (p2.x - p1.x) FROM > 0 => {IF p2.y # p1.y THEN ERROR; InnerDepthScanS[mother, p1.x, p2.x]}; < 0 => {IF p2.y # p1.y THEN ERROR; InnerDepthScanN[mother, p2.x, p1.x]}; ENDCASE => SELECT (p2.y - p1.y) FROM > 0 => InnerDepthScanE[mother, p1.y, p2.y]; < 0 => InnerDepthScanW[mother, p2.y, p1.y]; ENDCASE => ERROR; }; NOTFn: PROC [ ms: MaskState, spec: LIST OF REF ANY, extInfluenceDiameter: Tad _ 0 ] RETURNS [ result: Tesselation ] -- CoverProc -- = BEGIN ComplementTile: PROC [tile: CStitching.Tile, data: REF ANY] -- CStitching.PerTileProc -- = {result.ChangeRect[CDBasics.Intersection[CDBasics.universe, tile.Area], $covered]}; basis: Tesselation _ GenerateCover[ms, spec.first, extInfluenceDiameter]; result _ NewTesselation[NIL]; [] _ basis.EnumerateArea[rect: CDBasics.universe, eachTile: ComplementTile, skip: $covered]; basis _ DisposeTesselation[basis]; END; ANDFn: PROC [ ms: MaskState, spec: LIST OF REF ANY, extInfluenceDiameter: Tad _ 0 ] RETURNS [ result: Tesselation ] -- CoverProc -- = BEGIN NilTile: PROC [tile: CStitching.Tile, data: REF ANY] -- CStitching.PerTileProc -- = {result.ChangeRect[CDBasics.Intersection[CDBasics.universe, tile.Area], NIL]}; result _ GenerateCover[ms, spec.first, extInfluenceDiameter]; FOR rest: LIST OF REF ANY _ spec.rest, rest.rest WHILE rest # NIL DO term: Tesselation _ GenerateCover[ms, rest.first, extInfluenceDiameter]; [] _ term.EnumerateArea[rect: CDBasics.universe, eachTile: NilTile, skip: $covered]; term _ DisposeTesselation[term]; ENDLOOP; END; ANDNOTFn: PROC [ ms: MaskState, spec: LIST OF REF ANY, extInfluenceDiameter: Tad _ 0 ] RETURNS [ result: Tesselation ] -- CoverProc -- = BEGIN NilTile: PROC [tile: CStitching.Tile, data: REF ANY] -- CStitching.PerTileProc -- = {result.ChangeRect[CDBasics.Intersection[CDBasics.universe, tile.Area], NIL]}; result _ GenerateCover[ms, spec.first, extInfluenceDiameter]; FOR rest: LIST OF REF ANY _ spec.rest, rest.rest WHILE rest # NIL DO term: Tesselation _ GenerateCover[ms, rest.first, extInfluenceDiameter]; [] _ term.EnumerateArea[rect: CDBasics.universe, eachTile: NilTile, skip: NIL]; term _ DisposeTesselation[term]; ENDLOOP; END; ORFn: PROC [ ms: MaskState, spec: LIST OF REF ANY, extInfluenceDiameter: Tad _ 0 ] RETURNS [ result: Tesselation ] -- CoverProc -- = BEGIN CoverTile: PROC [tile: CStitching.Tile, data: REF ANY] -- CStitching.PerTileProc -- = {result.ChangeRect[tile.Area, $covered]}; layers: LIST OF CDLayer _ NIL; otherThings: LIST OF REF ANY _ NIL; FOR subList: LIST OF REF ANY _ spec, subList.rest WHILE subList # NIL DO WITH subList.first SELECT FROM layer: CDLayer => IF layer.deltaDiameter >= 0 THEN layers _ CONS[layer, layers] ELSE otherThings _ CONS[layer, otherThings]; ENDCASE => otherThings _ CONS[subList.first, otherThings]; ENDLOOP; IF otherThings = NIL THEN result _ NewTesselation[NIL] ELSE BEGIN result _ GenerateCover[ms, otherThings.first, extInfluenceDiameter]; FOR rest: LIST OF REF ANY _ otherThings.rest, rest.rest WHILE rest # NIL DO term: Tesselation _ GenerateCover[ms, rest.first, extInfluenceDiameter]; [] _ term.EnumerateArea[rect: CDBasics.universe, eachTile: CoverTile]; term _ DisposeTesselation[term]; ENDLOOP; END; IF layers # NIL THEN DrawLayersWithPosDeltas[ms: ms, rects: result, layers: layers, extInfluenceDiameter: extInfluenceDiameter]; END; RunRec: TYPE = RECORD [ desc: ROPE, areaInSqMeters: REAL _ 0, perimInMeters: Meters _ 0.0, runsInMeters: ARRAY Sense OF RECORD [ sense: ROPE, r: REF RunArray ] ]; RunArray: TYPE = RECORD [ ra: SEQUENCE size: NAT OF Meters ]; MeasureRuns: PROC [ ms: MaskState, spec: LIST OF REF ANY, extInfluenceDiameter: Tad _ 0 ] RETURNS [ result: Tesselation ] -- CoverProc -- = BEGIN PixelRunArray: TYPE = RECORD [ ra: SEQUENCE size: NAT OF MEBESPixels ]; TadCoverRec: TYPE = RECORD [ sense: ROPE, maxInterestDist, minFeature: Tad _ 0, r: REF PixelRunArray ]; areaInSqPixels: INT _ 0; perimInPixels: MEBESPixels _ 0; table: ARRAY Sense OF REF TadCoverRec _ ALL[NIL]; runRef: REF RunRec _ NIL; -- for external consumption mebesPixelPitch: Meters _ ms.mebesPixelPitch -- nm -- *1.0E-9; tadsPerPixel: Tad = ms.mebesPixelPitch*ms.tadsPerNm; LookForRuns: PROC [tile: CStitching.Tile, data: REF ANY] -- CStitching.PerTileProc -- = BEGIN ComplainAboutFeature: PROC [ dia: Tad, pos: TadPosition ] = BEGIN chose: NAT = ComplainAt[ms: ms, pos: pos, explanation: IO.PutFR["Too-small %g", IO.rope[c.sense]], choice: LIST ["Reduce min feature", "Proceed"]]; SELECT chose FROM 1 => c.minFeature _ dia; ENDCASE => NULL; END; EWRuns: PROC [ cov: CStitching.Tile, x1, x2: Tad ] = BEGIN IF cov.NEdge < keyTileArea.y2+c.maxInterestDist THEN BEGIN covHeightTads: Tad = cov.NEdge-keyTileArea.y2; covHeightPixels: MEBESPixels = covHeightTads/tadsPerPixel; FOR tile: CStitching.Tile _ cov.EN, tile.SW WHILE x1 < tile.EEdge DO tx1: Tad = MAX[x1, tile.WEdge]; tx2: Tad = MIN[x2, tile.EEdge]; dxPixels: MEBESPixels = (tx2-tx1)/tadsPerPixel; SELECT TRUE FROM tx2 <= tx1 => NULL; tile.value # keyTilevalue => BEGIN IF covHeightTads = 0 THEN perimInPixels _ perimInPixels+dxPixels; EWRuns[cov: tile, x1: tx1, x2: tx2]; END; covHeightTads >= c.minFeature => c.r[covHeightPixels] _ c.r[covHeightPixels]+dxPixels; covHeightTads > 0 => -- IN (0..minFeature) -- BEGIN ComplainAboutFeature[covHeightTads, [x: (tx1+tx2)/2, y: (cov.NEdge+keyTileArea.y2)/2]]; c.r[covHeightPixels] _ c.r[covHeightPixels]+dxPixels; END; ENDCASE => NULL; ENDLOOP; END; END; -- of EWRuns NSRuns: PROC [ cov: CStitching.Tile, y1, y2: Tad ] = BEGIN IF cov.EEdge < keyTileArea.x2+c.maxInterestDist THEN BEGIN covWidthTads: Tad = cov.EEdge-keyTileArea.x2; covWidthPixels: MEBESPixels = covWidthTads/tadsPerPixel; FOR tile: CStitching.Tile _ cov.NE, tile.WS WHILE y1 < tile.NEdge DO ty1: MEBESPixels = MAX[y1, tile.SEdge]; ty2: MEBESPixels = MIN[y2, tile.NEdge]; dyPixels: MEBESPixels = (ty2-ty1)/tadsPerPixel; SELECT TRUE FROM ty2 <= ty1 => NULL; tile.value # keyTilevalue => BEGIN IF covWidthTads = 0 THEN perimInPixels _ perimInPixels+dyPixels; NSRuns[cov: tile, y1: ty1, y2: ty2]; END; covWidthTads >= c.minFeature => c.r[covWidthPixels] _ c.r[covWidthPixels]+dyPixels; covWidthTads > 0 => -- IN (0..minFeature) -- BEGIN ComplainAboutFeature[covWidthTads, [x: (cov.EEdge+keyTileArea.x2)/2, y: (ty1+ty2)/2]]; c.r[covWidthPixels] _ c.r[covWidthPixels]+dyPixels; END; ENDCASE => NULL; ENDLOOP; END; END; -- of NSRuns keyTilevalue: REF ANY = tile.value; c: REF TadCoverRec = table[(IF keyTilevalue = NIL THEN cover ELSE space)]; keyTileArea: TadRect = tile.Area; clippedKeyTileArea: TadRect = CDBasics.Intersection[ms.tadStripeClip, keyTileArea]; IF keyTilevalue # NIL THEN areaInSqPixels _ areaInSqPixels+ ((clippedKeyTileArea.x2-clippedKeyTileArea.x1)/tadsPerPixel)* ((clippedKeyTileArea.y2-clippedKeyTileArea.y1)/tadsPerPixel); IF keyTileArea.y2 IN (ms.tadStripeClip.y1 .. ms.tadStripeClip.y2] THEN EWRuns[cov: tile, x1: clippedKeyTileArea.x1, x2: clippedKeyTileArea.x2]; IF keyTileArea.x2 IN (ms.tadStripeClip.x1 .. ms.tadStripeClip.x2] THEN NSRuns[cov: tile, y1: clippedKeyTileArea.y1, y2: clippedKeyTileArea.y2]; END; -- of LookForRuns GetCoverRec: PROC [sense: ROPE, l: LIST OF REF ANY] RETURNS [c: REF TadCoverRec] = BEGIN c _ NEW[TadCoverRec _ [sense: sense]]; c.maxInterestDist _ NARROW[l.first, REF Nm]^*ms.tadsPerNm; c.minFeature _ NARROW[l.rest.first, REF Nm]^*ms.tadsPerNm; c.r _ NEW[PixelRunArray[c.maxInterestDist/(ms.mebesPixelPitch*ms.tadsPerNm)]]; FOR width: MEBESPixels IN [0..c.r.size) DO c.r[width] _ 0; ENDLOOP; END; table[cover] _ GetCoverRec["cover", spec.rest.rest]; table[space] _ GetCoverRec["space", spec.rest.rest.rest.rest]; result _ GenerateCover[ms, spec.rest.first, extInfluenceDiameter+MAX[table[cover].maxInterestDist, table[space].maxInterestDist]]; [] _ result.EnumerateArea[rect: ms.tadStripeClip, eachTile: LookForRuns, skip: $none]; ms.data _ runRef _ NEW[RunRec _ [ desc: NARROW[spec.first], areaInSqMeters: areaInSqPixels*mebesPixelPitch*mebesPixelPitch, perimInMeters: perimInPixels*mebesPixelPitch, runsInMeters: [ space: [sense: "space", r: NEW[RunArray[table[space].r.size]]], cover: [sense: "cover", r: NEW[RunArray[table[cover].r.size]]] ] ]]; FOR sense: Sense IN Sense DO FOR width: MEBESPixels IN [0..table[sense].r.size) DO runRef.runsInMeters[sense].r[width] _ table[sense].r[width]*mebesPixelPitch; ENDLOOP; ENDLOOP; END; RestrictedEnlarge: PROC [ ms: MaskState, spec: LIST OF REF ANY, extInfluenceDiameter: Tad _ 0 ] RETURNS [ result: Tesselation ] -- CoverProc -- = BEGIN PlaceNImplant: PROC [tile: CStitching.Tile, data: REF ANY] -- CStitching.PerTileProc -- = BEGIN InteractWithPImplant: PROC [tile: CStitching.Tile, data: REF ANY] -- CStitching.PerTileProc -- = BEGIN pTile: CStitching.Tile = tile; pTileArea: TadRect = pTile.Area; aVsB: Direction; biggestGap: Tad _ -1; gaps: ARRAY Direction OF Tad _ ALL[maxRadialExtension]; deInsertedArea: TadRect; [aVsB, biggestGap] _ Juxtaposition[a: pTileArea, b: nTileArea]; IF biggestGap<0 THEN ERROR; -- design rule violation IF NOT anyInteractingPImplant THEN BEGIN anyInteractingPImplant _ TRUE; nImplPieces.ChangeRect[CDBasics.universe, NIL]; nImplPieces.ChangeRect[desiredNImplant, $covered]; END; gaps[aVsB] _ biggestGap/2; deInsertedArea _ [x1: pTileArea.x1-gaps[E], y1: pTileArea.y1-gaps[N], x2: pTileArea.x2+gaps[W], y2: pTileArea.y2+gaps[S]]; IF CDBasics.NonEmpty[deInsertedArea] THEN nImplPieces.ChangeRect[deInsertedArea, NIL]; END; CoverNegotiatedPiece: PROCEDURE [tile: CStitching.Tile, data: REF ANY] -- CStitching.PerTileProc -- = {area: TadRect = tile.Area; result.ChangeRect[area, $covered]}; nTile: CStitching.Tile = tile; nTileArea: TadRect = nTile.Area; desiredNImplant: TadRect = CDBasics.Extend[nTileArea, maxRadialExtension]; anyInteractingPImplant: BOOL _ FALSE; [] _ pDif.EnumerateArea[rect: CDBasics.Extend[nTileArea, 2*maxRadialExtension], eachTile: InteractWithPImplant]; IF NOT anyInteractingPImplant THEN result.ChangeRect[desiredNImplant, $covered] ELSE [] _ nImplPieces.EnumerateArea[desiredNImplant, CoverNegotiatedPiece]; END; maxRadialExtension: Tad = NARROW[spec.first, REF Nm]^*ms.tadsPerNm; nDif: Tesselation _ GenerateCover[ms, spec.rest.first, extInfluenceDiameter+2*maxRadialExtension]; pDif: Tesselation _ GenerateCover[ms, spec.rest.rest.first, extInfluenceDiameter+2*maxRadialExtension]; nImplPieces: Tesselation _ NewTesselation[]; result _ NewTesselation[]; [] _ nDif.EnumerateArea[rect: CDBasics.universe, eachTile: PlaceNImplant]; nDif _ DisposeTesselation[nDif]; pDif _ DisposeTesselation[pDif]; nImplPieces _ DisposeTesselation[nImplPieces]; END; EnlargeSparse: PROC [ ms: MaskState, spec: LIST OF REF ANY, extInfluenceDiameter: Tad _ 0 ] RETURNS [ result: Tesselation ] -- CoverProc -- = BEGIN EnlargeToThe: PROC [ curDir: Direction, sideSpacing: Tad ] = { Enlarge: PROC [tile: CStitching.Tile, data: REF] -- CStitching.TileProc -- = { tileArea: TadRect = tile.Area; enlargedArea: TadRect = [ x1: tile.WEdge-enlargeTable[W], y1: tile.SEdge-enlargeTable[S], x2: tile.EEdge+enlargeTable[E], y2: tile.NEdge+enlargeTable[N]]; result.ChangeRect[enlargedArea, $covered]; }; Clip: PROC [tile: CStitching.Tile, data: REF] -- CStitching.TileProc -- = { ClipS: PROC [tile: CStitching.Tile, data: REF] -- CStitching.TileProc -- = { x1: Tad = MAX[tile.WEdge, clipBasisTile.WEdge]; x2: Tad = MIN[tile.EEdge, clipBasisTile.EEdge]; IF x1 < x2 THEN result.ChangeRect[[x1: x1-sideSpacing, y1: clipBasisTile.SEdge-minSpacing, x2: x2+sideSpacing, y2: clipBasisTile.SEdge], NIL]; }; ClipN: PROC [tile: CStitching.Tile, data: REF] -- CStitching.TileProc -- = { x1: Tad = MAX[tile.WEdge, clipBasisTile.WEdge]; x2: Tad = MIN[tile.EEdge, clipBasisTile.EEdge]; IF x1 < x2 THEN result.ChangeRect[[x1: x1-sideSpacing, y1: clipBasisTile.NEdge, x2: x2+sideSpacing, y2: clipBasisTile.NEdge+minSpacing], NIL]; }; ClipW: PROC [tile: CStitching.Tile, data: REF] -- CStitching.TileProc -- = { y1: Tad = MAX[tile.SEdge, clipBasisTile.SEdge]; y2: Tad = MIN[tile.NEdge, clipBasisTile.NEdge]; IF y1 < y2 THEN result.ChangeRect[[x1: clipBasisTile.WEdge-minSpacing, y1: y1-sideSpacing, x2: clipBasisTile.WEdge, y2: y2+sideSpacing], NIL]; }; ClipE: PROC [tile: CStitching.Tile, data: REF] -- CStitching.TileProc -- = { y1: Tad = MAX[tile.SEdge, clipBasisTile.SEdge]; y2: Tad = MIN[tile.NEdge, clipBasisTile.NEdge]; IF y1 < y2 THEN result.ChangeRect[[x1: clipBasisTile.EEdge, y1: y1-sideSpacing, x2: clipBasisTile.EEdge+minSpacing, y2: y2+sideSpacing], NIL]; }; clipBasisTile: CStitching.Tile = tile; basis.EnumerateNeighborhood[tile: tile, eachTileS: (IF curDir = N THEN ClipS ELSE NIL), eachTileW: (IF curDir = E THEN ClipW ELSE NIL), eachTileN: (IF curDir = S THEN ClipN ELSE NIL), eachTileE: (IF curDir = W THEN ClipE ELSE NIL), skip: $covered]; }; IncludeOriginal: PROC [tile: CStitching.Tile, data: REF] -- CStitching.TileProc -- = { tileArea: TadRect = tile.Area; result.ChangeRect[tile.Area, $covered]; }; enlargeTable: ARRAY Direction OF Tad; FOR d: Direction IN Direction DO enlargeTable[d] _ (IF d = curDir THEN maxRadialEnlargement ELSE 0); ENDLOOP; result _ CStitching.NewTesselation[]; basis.EnumerateArea[rect: CDBasics.universe, eachTile: Enlarge]; basis.EnumerateArea[rect: CDBasics.universe, eachTile: Clip]; basis.EnumerateArea[rect: CDBasics.universe, eachTile: IncludeOriginal]; basis _ DisposeTesselation[basis]; basis _ result; }; maxRadialEnlargement: Tad = NARROW[spec.first, REF Nm]^*ms.tadsPerNm; minSpacing: Tad = NARROW[spec.rest.first, REF Nm]^*ms.tadsPerNm; basis: Tesselation _ GenerateCover[ms, spec.rest.rest.first, extInfluenceDiameter+2*maxRadialEnlargement+minSpacing]; EnlargeToThe[N, minSpacing+2*maxRadialEnlargement]; EnlargeToThe[S, minSpacing+2*maxRadialEnlargement]; EnlargeToThe[E, minSpacing]; EnlargeToThe[W, minSpacing]; basis _ NIL; END; EnlargeFn: PROC [ ms: MaskState, spec: LIST OF REF ANY, extInfluenceDiameter: Tad _ 0 ] RETURNS [ result: Tesselation ] -- CoverProc -- = BEGIN deltaDiameterNm: Nm = NARROW[spec.first, REF Nm]^; deltaDiameterTads: MEBESPixels = deltaDiameterNm*ms.tadsPerNm; SELECT deltaDiameterTads FROM =0 => result _ GenerateCover[ms, spec.rest.first, extInfluenceDiameter]; >0 => BEGIN EnlargeTile: PROC [tile: CStitching.Tile, data: REF ANY] -- CStitching.PerTileProc -- = {result.ChangeRect[Bloat[tile.Area, deltaDiameterTads], tile.value]}; basis: Tesselation _ GenerateCover[ms, spec.rest.first, extInfluenceDiameter+deltaDiameterTads]; result _ NewTesselation[NIL]; [] _ basis.EnumerateArea[rect: CDBasics.universe, eachTile: EnlargeTile]; basis _ DisposeTesselation[basis]; END; <0 => BEGIN EnlargeGap: PROC [tile: CStitching.Tile, data: REF ANY] -- CStitching.PerTileProc -- = {result.ChangeRect[CDBasics.Intersection[CDBasics.universe, Bloat[tile.Area, -deltaDiameterTads]], tile.value]}; basis: Tesselation _ GenerateCover[ms, spec.rest.first, extInfluenceDiameter-deltaDiameterTads]; result _ NewTesselation[NIL]; result.ChangeRect[CDBasics.universe, $covered]; [] _ basis.EnumerateArea[rect: CDBasics.universe, eachTile: EnlargeGap, skip: $covered]; basis _ DisposeTesselation[basis]; END; ENDCASE => ERROR; END; DeNotchFn: PROC [ ms: MaskState, spec: LIST OF REF ANY, extInfluenceDiameter: Tad _ 0 ] RETURNS [ result: Tesselation ] -- CoverProc -- = BEGIN deltaDiams: ARRAY [-1..2] OF Nm _ ALL[0]; ndd: [0..2]; newSpec: REF; FOR ndd_0, ndd+1 WHILE ndd<2 DO WITH spec.first SELECT FROM rnm: REF Nm => {deltaDiams[ndd] _ rnm^; spec _ spec.rest}; ENDCASE => EXIT; ENDLOOP; newSpec _ spec.first; FOR i: [0..2] IN [0..ndd] DO IF deltaDiams[i] # deltaDiams[i-1] THEN newSpec _ LIST[$Enlarge, NEW[Nm _ (deltaDiams[i]-deltaDiams[i-1])], newSpec]; ENDLOOP; result _ GenerateCover[ms, newSpec, extInfluenceDiameter]; END; SizeLEqFn: PROC [ ms: MaskState, spec: LIST OF REF ANY, extInfluenceDiameter: Tad _ 0 ] RETURNS [ result: Tesselation ] -- CoverProc -- = BEGIN sieveWidth: Nm = NARROW[spec.first, REF Nm]^; sieveHeight: Nm = NARROW[spec.rest.first, REF Nm]^; sieveWidthTads: MEBESPixels = MAX[sieveWidth, sieveHeight]*ms.tadsPerNm; sieveHeightTads: MEBESPixels = MIN[sieveWidth, sieveHeight]*ms.tadsPerNm; BEGIN SizeFilterTile: PROC [tile: CStitching.Tile, data: REF ANY] -- CStitching.PerTileProc -- = { tileWidth, tileHeight: Tad; IsolatedTile: PROC [tile: CStitching.Tile] RETURNS [b:BOOLEAN] ~ { en: CStitching.Tile _ tile.EN; ws: CStitching.Tile _ tile.WS; b _ ( (en.value # tile.value) AND (en.WEdge < tile.WEdge) AND (ws.value # tile.value) AND (ws.EEdge > tile.EEdge) ); }; tileWidth _ MAX[(tile.EEdge - tile.WEdge), (tile.NEdge - tile.SEdge)]; tileHeight _ MIN[(tile.EEdge - tile.WEdge), (tile.NEdge - tile.SEdge)]; IF ( IsolatedTile[tile] AND (sieveWidthTads >= tileWidth) AND (sieveHeightTads >= tileHeight) ) THEN result.ChangeRect[rect: tile.Area, new: $covered]; }; result _ CStitching.NewTesselation[]; [] _ CStitching.EnumerateArea[ plane: GenerateCover[ms, spec.rest.rest.first, extInfluenceDiameter], rect: CDBasics.universe, eachTile: SizeFilterTile]; END; END; Init: PROC = BEGIN Atom.PutProp[$CDMEBESCoverProcs, $NOT, NEW[CoverProc _ NOTFn]]; Atom.PutProp[$CDMEBESCoverProcs, $AND, NEW[CoverProc _ ANDFn]]; Atom.PutProp[$CDMEBESCoverProcs, $ANDNOT, NEW[CoverProc _ ANDNOTFn]]; Atom.PutProp[$CDMEBESCoverProcs, $OR, NEW[CoverProc _ ORFn]]; Atom.PutProp[$CDMEBESCoverProcs, $MeasureRuns, NEW[CoverProc _ MeasureRuns]]; Atom.PutProp[$CDMEBESCoverProcs, $RestrictedEnlarge, NEW[CoverProc _ RestrictedEnlarge]]; Atom.PutProp[$CDMEBESCoverProcs, $EnlargeSparse, NEW[CoverProc _ EnlargeSparse]]; Atom.PutProp[$CDMEBESCoverProcs, $Enlarge, NEW[CoverProc _ EnlargeFn]]; Atom.PutProp[$CDMEBESCoverProcs, $DeNotch, NEW[CoverProc _ DeNotchFn]]; Atom.PutProp[$CDMEBESCoverProcs, $SizeLEq, NEW[CoverProc _ SizeLEqFn]]; END; Init[]; END. -- of CDMEBESGeomFns PCDMEBESGeomFns.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. McCreight, December 10, 1986 6:24:56 pm PST Hoel, February 27, 1986 3:33:39 pm PST Last Edited by: McCreight July 30, 1987 5:32:29 pm PDT **** S U P P O R T R O U T I N E S **** -- z1 < z2 -- z1 < z2 -- z1 < z2 -- z1 < z2 By convention, the depth scan proceeds to the right from the line p1 -> p2. ***** M A S K O P E R A T I O N R O U T I N E S ***** This is a very common case, so we speed it up by separating it into two lists: CDLayer's with nonnegative deltaDiameter's, and other things. We compute the other things first, and then take a single pass at the design for the CDLayer's with nonnegative deltaDiameter's. We examine first the north and then the east neighbors of this key rectangle, noting the nearest rectangle of the same kind in the direction of view. tile and clipBasisTile adjoin and form a material edge tile and clipBasisTile adjoin and form a material edge tile and clipBasisTile adjoin and form a material edge tile and clipBasisTile adjoin and form a material edge SizeLEq returns a tesselation of all isolated $covered rectangles from input tesselation L3 which are no larger than L1 x L2 nanometers, where L1, L2, and L3 are the elements of spec. Shapes larger than L1 x L2 nanometers, as well as non-rectangular shapes, are omitted. This was added February 27, 1986 to handle VTI's requirement to enlarge minimum size vias over diffusion. JHH. Returns TRUE iff tile doesn't touch other tiles of the same value. Assumes the cornerstitched plane has tiles of only two values. Κ@˜Jšœ™Icodešœ Οmœ1™<™+K™&K™6—K™šΟk ˜ Jšœžœ žœžœ˜,J˜—šΠbnœžœž˜Jšžœžœžœ˜1Jšžœžœžœ˜J˜J˜Jšœ/™/J˜Jšœ žœ˜#J˜Jš œžœ žœΟnœ œ œ œ˜JJ˜š  œžœžœ2˜_Jšœ ˜ Jšžœ!žœ˜FJšžœ!žœ˜FJšžœ!žœ˜FJšžœ!žœ˜FJšœ˜J˜—š  œžœ žœažœžœ˜“J˜š œžœ+˜@JšΟc ™ Jšœ"˜"Jšžœžœ˜7šžœ˜Kš žœ#žœ žœžœž˜Tšžœžœ˜Kšžœžœ#žœ˜SKšžœžœžœ˜TK˜Kšžœ˜—J˜—Jšœ˜J˜—š œžœ+˜@Jš‘ ™ Jšœ"˜"Jšžœžœ˜7šžœ˜š žœ#žœ žœžœž˜Tšžœžœ˜Kšžœžœ#žœ˜SKšžœžœžœ˜TK˜—Kšžœ˜—J˜—Jšœ˜J˜—š œžœ+˜@Jš‘ ™ Jšœ"˜"Jšžœžœ˜7šžœ˜Kš žœ"žœ žœžœž˜Qšžœžœ˜Kšžœžœ"žœ˜RKšžœžœžœ˜QK˜Kšžœ˜—J˜—Jšœ˜J˜—š œžœ+˜@Jš‘ ™ Jšœ"˜"Jšžœžœ˜7šžœ˜Kš žœ"žœ žœžœž˜Qšžœžœ˜Kšžœžœ"žœ˜RKšžœžœžœ˜QK˜Kšžœ˜—J˜—Jšœ˜J˜—JšœK™Kšžœž˜Jšœžœ žœžœ'˜HJšœžœ žœžœ'˜Hšžœ˜ šžœž˜Jšœ+˜+Jšœ+˜+Jšžœžœ˜———J˜J˜J˜J˜—Jšœ>™>J˜š œžœžœžœžœžœ"žœ‘œ˜…Jšž˜J˜š  œžœžœžœ‘œ˜ZJšœS˜SJ˜—JšœI˜IJšœžœ˜Jšœ\˜\Jšœ"˜"Jšžœ˜—J˜J˜š œžœžœžœžœžœ"žœ‘œ˜…Jšž˜J˜š  œžœžœžœ‘œ˜SJšœHžœ˜NJ˜—Jšœ=˜=šžœžœžœžœžœžœžœž˜DJšœH˜HJšœT˜TJšœ ˜ Jšžœ˜—Jšžœ˜J˜J˜—š œžœžœžœžœžœ"žœ‘œ˜ˆJšž˜J˜š  œžœžœžœ‘œ˜SJšœHžœ˜NJ˜—Jšœ=˜=šžœžœžœžœžœžœžœž˜DJšœH˜HJšœJžœ˜OJšœ ˜ Jšžœ˜—Jšžœ˜J˜J˜—š œžœžœžœžœžœ"žœ‘œ˜„Jšž˜JšœŽ™ŽJ˜š   œžœžœžœ‘œ˜UJšœ)˜)J˜—Jšœžœžœ žœ˜Jš œ žœžœžœžœžœ˜#šžœ žœžœžœžœžœ žœž˜Hšžœžœž˜šœ˜Jšžœžœ žœ˜=Jšžœžœ˜,—Jšžœžœ˜:—šžœ˜J˜——Jšžœžœžœžœ˜6šž˜Jšž˜JšœD˜Dšžœžœžœžœžœžœžœž˜KJšœH˜HJšœF˜FJšœ ˜ Jšžœ˜—Jšžœ˜J˜—šžœ žœž˜Jšœk˜k—Jšžœ˜J˜J˜—J˜šΟbœžœžœ˜Jšœžœ˜ Jšœžœ˜Jšœ˜šœžœžœžœ˜%Jšœžœ˜ Jšœžœ ˜Jšœ˜—Jšœ˜J˜—Jš ’œžœžœžœžœžœ ˜=J˜š  œžœžœžœžœžœ"žœ‘œ˜‹Jšž˜J˜Jš œžœžœžœžœžœ˜GJš œ žœžœ žœ+žœ˜gJ˜Jšœžœ˜Jšœ˜Jš œžœžœžœžœžœ˜1Jšœžœ žœ‘˜5Jšœ-‘œ ˜>Jšœ4˜4J˜š   œžœžœžœ‘œ˜WJšž˜J˜š œžœ!˜;Jšž˜šœžœ˜)Jšœ žœžœ˜8Jšœžœ$˜0—šžœž˜Jšœ˜Jšžœžœ˜—Jšžœ˜J˜—š œžœ(˜4Jšž˜šžœ.ž˜4Jšž˜Jšœ.˜.Jšœ:˜:šžœ)žœž˜DJšœ žœ˜Jšœ žœ˜Jšœ/˜/šžœžœž˜Jšœžœ˜šœ˜Jšž˜šžœž˜Jšœ'˜'—Jšœ$˜$Jšžœ˜—šœ ˜ Jšœ5˜5—šœ‘˜-Jšž˜JšœW˜WJšœ5˜5Jšžœ˜—Jšžœžœ˜—Jšžœ˜—Jšžœ˜—Jšžœ‘ ˜J˜—š œžœ(˜4Jšž˜šžœ.ž˜4Jšž˜Jšœ-˜-Jšœ8˜8šžœ)žœž˜DJšœžœ˜'Jšœžœ˜'Jšœ/˜/šžœžœž˜Jšœžœ˜šœ˜Jšž˜Jšžœžœ(˜@Jšœ$˜$Jšžœ˜—šœ˜Jšœ3˜3—šœ‘˜,Jšž˜JšœV˜VJšœ3˜3Jšžœ˜—Jšžœžœ˜—Jšžœ˜—Jšžœ˜—Jšžœ‘ ˜J˜—Jšœžœžœ˜#Jš œžœžœžœžœžœ ˜JJšœ!˜!šœS˜SJ˜—šžœžœž˜šœ ˜ šœ=˜=Jšœ=˜=——J˜—Jšœ•™•šžœžœ.ž˜FJšœH˜H—šžœžœ.ž˜FJšœH˜H—Jšžœ‘˜J˜J˜—š  œžœ žœžœžœžœžœžœžœ˜RJšž˜Jšœžœ˜&Jšœžœ žœ˜:Jšœžœžœ˜:JšœžœE˜Nšžœžœž˜*Jšœ˜Jšžœ˜—Jšžœ˜J˜—Jšœ4˜4Jšœ>˜>JšœAžœ>˜‚JšœV˜VJ˜šœžœ ˜!Jšœžœ ˜Jšœ?˜?Jšœ-˜-šœ˜Jšœžœ!˜?Jšœžœ ˜>J˜—Jšœ˜J˜—šžœžœž˜šžœžœž˜5JšœL˜LJšžœ˜—Jšžœ˜J˜—Jšžœ˜J˜—š œžœžœžœžœžœ"žœ‘œ˜‘Jšž˜J˜š   œžœžœžœ‘œ˜YJšž˜J˜š  œžœžœžœ‘œ˜`Jšž˜Jšœ˜J˜ Jšœ˜Jšœ˜Jšœžœ žœžœ˜7Jšœ˜J˜Jšœ?˜?J˜Jšžœžœžœ‘˜4šžœžœž˜"Jšž˜Jšœžœ˜Jšœ*žœ˜/Jšœ2˜2Jšžœ˜—Jšœ˜Jšœz˜zšžœ#ž˜)Jšœ'žœ˜,—Jšžœ˜J˜—š  œž œžœžœ‘œ˜eJšœ?˜?J˜—Jšœ˜J˜ JšœJ˜JJšœžœžœ˜%Jšœp˜pJšžœžœžœ-˜OJšžœH˜LJšžœ˜J˜—Jšœžœ žœ˜CJšœb˜bJšœg˜gJšœ,˜,Jšœ˜JšœJ˜JJšœ ˜ Jšœ ˜ Jšœ.˜.Jšžœ˜J˜J˜—š  œžœžœžœžœžœ"žœ‘œ˜Jšž˜J˜š  œžœ,˜>J˜š œžœžœ‘œ˜NJšœ˜šœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ ˜ —Jšœ*˜*Jšœ˜J˜—š œžœžœ‘œ˜KJ˜š œžœžœ‘œ˜LJšœ6™6Jšœ žœ"˜/Jšœ žœ"˜/šžœ ž˜Jšœyžœ˜~—Jšœ˜J˜—š œžœžœ‘œ˜LJšœ6™6Jšœ žœ"˜/Jšœ žœ"˜/šžœ ž˜Jšœyžœ˜~—Jšœ˜J˜—š œžœžœ‘œ˜LJšœ6™6Jšœ žœ"˜/Jšœ žœ"˜/šžœ ž˜Jšœyžœ˜~—Jšœ˜J˜—š œžœžœ‘œ˜LJšœ6™6Jšœ žœ"˜/Jšœ žœ"˜/šžœ ž˜Jšœyžœ˜~—Jšœ˜J˜—Jšœ&˜&šœ'˜'Jš œ žœ žœžœžœ˜/Jš œ žœ žœžœžœ˜/Jš œ žœ žœžœžœ˜/Jš œ žœ žœžœžœ˜/Jšœ˜—Jšœ˜J˜—š œžœžœ‘œ˜VJšœ˜Jšœ'˜'Jšœ˜J˜—Jšœžœ žœ˜%šžœžœ ž˜ Jšœžœ žœžœ˜CJšžœ˜—Jšœ%˜%Jšœ@˜@Jšœ=˜=JšœH˜HJ˜"Jšœ˜Jšœ˜J˜—Jšœžœ žœ˜EJšœžœžœ˜@Jšœu˜uJšœ3˜3Jšœ3˜3Jšœ˜Jšœ˜Jšœžœ˜ Jšžœ˜J˜J˜—š  œžœžœžœžœžœ"žœ‘œ˜‰Jšž˜Jšœžœ žœ˜2Jšœ>˜>šžœž˜JšœH˜Hšœ˜Jšž˜J˜š   œžœžœžœ‘œ˜WJšœE˜EJ˜—Jšœ`˜`Jšœžœ˜JšœI˜IJšœ"˜"Jšžœ˜J˜—šœ˜Jšž˜J˜š   œžœžœžœ‘œ˜VJšœp˜pJ˜—Jšœ`˜`Jšœžœ˜Jšœ/˜/JšœX˜XJšœ"˜"Jšžœ˜J˜—Jšžœžœ˜—Jšžœ˜J˜J˜—š  œžœžœžœžœžœ"žœ‘œ˜‰Jšž˜Jšœ žœ žœžœ˜)Jšœ ˜ Jšœ žœ˜ šžœžœž˜šžœ žœž˜Jšœžœ2˜:Jšžœžœ˜—Jšžœ˜—Jšœ˜šžœ žœ ž˜šžœ!ž˜'Jšœ žœ žœ1˜M—Jšžœ˜—Jšœ:˜:Jšžœ˜J˜J˜—š  œžœžœžœžœžœ"žœ‘Πce ‘œ˜‰K™K™€K™Kšž˜Kšœžœ žœ˜-Kšœžœžœ˜3Kšœžœ'˜HKšœžœ'˜I˜Kšž˜K˜š  œžœžœžœ£œ˜\Kšœ˜K˜K˜š  œžœžœžœ˜BKšœB™BKšœ>™>K˜Kšœ˜Kšœ˜˜Kšœžœž˜7Kšœžœ˜3K˜—K˜—K˜Kšœ žœ7˜FKšœ žœ7˜Gšžœ˜Kšœž˜Kšœž˜!Kšœ˜Kšœž˜K˜2—šœ˜K˜——Kšœ%˜%˜K˜EK˜K˜—Kšžœ˜—K˜Kšžœ˜J˜—š œžœ˜ Jšž˜Jšœ'žœ˜?Jšœ'žœ˜?Jšœ*žœ˜EJšœ&žœ˜=Jšœ/žœ˜MJšœ5žœ!˜YJšœ1žœ˜QJšœ+žœ˜GJšœ+žœ˜GJšœ+žœ˜GJšžœ˜—J˜J˜Jšžœ‘˜—K™J˜J˜J˜—…—Oδmt