DIRECTORY Atom, CD, CDBasics, CornerBasedDRC, CStitching, Rope; CornerBasedDRCImpl: CEDAR PROGRAM IMPORTS CD, CDBasics, CStitching EXPORTS CornerBasedDRC = BEGIN OPEN CornerBasedDRC; Quadrants: TYPE = {ne, nw, sw, se}; DefaultError: ErrorProc = { }; DefaultCompatibleNodes: CompatibleNodesProc = { RETURN [FALSE]; }; neverInTesselation: REF ATOM _ NEW[ATOM_$neverInTesselation]; stopped: ERROR = CODE; Check: PUBLIC PROC [task: REF DrcTask, area: CD.Rect] = { IF task.geometry.stopFlag=NIL THEN task.geometry.stopFlag_NEW[BOOL_FALSE]; IF task.compatibleNodes=NIL THEN task.compatibleNodes _ DefaultCompatibleNodes; IF task.error=NIL THEN task.error _ DefaultError; [] _ CStitching.EnumerateArea[plane: task.geometry, rect: area, eachTile: CheckOneTile, skip: neverInTesselation, data: task ! stopped => GOTO hasStopped]; EXITS hasStopped => NULL; }; CompatibleNodes: PROC [task: REF DrcTask, rule: Rule, corner: REF, pos: CD.Position, other: REF, r: CD.Rect _ CDBasics.empty] RETURNS [BOOL] = INLINE { RETURN [ corner=other OR task.compatibleNodes[task, rule, corner, pos, other, r] ] }; CheckOneTile: CStitching.TileProc = { task: REF DrcTask = NARROW[data]; r: CD.Rect = CStitching.Area[tile]; CheckCorner: PROC [quadVals: ARRAY Quadrants OF REF ANY, pos: CD.Position] = { CheckArea: PROC [rule: Rule, orient: CD.Orientation, flavour: { convex, concave}] = { CheckTileValue: CStitching.TileProc = { CheckValue[tile.value, CStitching.Area[tile]] }; CheckValue: PROC [value: REF ANY, area: CD.Rect] = { IF value=NIL THEN { IF ~rule.isError[spaceConstraintIndex] THEN RETURN; } ELSE WITH value SELECT FROM cc: Constraint => { IF ~rule.isError[cc.index] THEN RETURN; IF rule.okIfConnected AND nodeOrConstraintAtCorner#NIL AND CompatibleNodes[task, rule, nodeOrConstraintAtCorner, pos, cc, area] THEN RETURN; }; ENDCASE => { IF ~rule.isError[nodeConstraintIndex] THEN RETURN; IF rule.okIfConnected AND nodeOrConstraintAtCorner#NIL AND CompatibleNodes[task, rule, nodeOrConstraintAtCorner, pos, value] THEN RETURN; }; IF ~notReportedYet THEN RETURN; IF task.restrict#NIL THEN { IF ~CStitching.IsEmpty[ plane: task.restrict, rect: CDBasics.MapRect[itemInCell: [x1: -delta, y1: -delta, x2: len, y2: len], cellInWorld: [pos, orient]], skip: task.skipThese ] THEN RETURN; }; task.error[ task: task, rule: rule, r: CDBasics.MapRect[itemInCell: [x1: 0, y1: 0, x2: rule.extent, y2: rule.extent], cellInWorld: [pos, orient]] ]; notReportedYet _ FALSE }; -- CheckValue notReportedYet: BOOL _ TRUE; len: INT = rule.extent; delta: INT = 1; IF len = 0 THEN { IF notReportedYet THEN CheckValue[quadVals[ne], [pos.x, pos.y, pos.x+delta, pos.y+delta]]; IF notReportedYet THEN CheckValue[quadVals[nw], [pos.x, pos.y-delta, pos.x+delta, pos.y]]; IF notReportedYet THEN CheckValue[quadVals[sw], [pos.x-delta, pos.y-delta, pos.x, pos.y]]; IF notReportedYet THEN CheckValue[quadVals[se], [pos.x-delta, pos.y, pos.x, pos.y+delta]]; } ELSE { SELECT flavour FROM convex => { [] _ CStitching.EnumerateArea[ plane: task.geometry, rect: CDBasics.MapRect[itemInCell: [x1: -delta, y1: 0, x2: len, y2: len], cellInWorld: [pos, orient]], eachTile: CheckTileValue, skip: neverInTesselation ]; [] _ CStitching.EnumerateArea[ plane: task.geometry, rect: CDBasics.MapRect[itemInCell: [x1: 0, y1: -delta, x2: len, y2: 0], cellInWorld: [pos, orient]], eachTile: CheckTileValue, skip: neverInTesselation ]; }; concave => { [] _ CStitching.EnumerateArea[ plane: task.geometry, rect: CDBasics.MapRect[itemInCell: [x1: 0, y1: 0, x2: len, y2: len], cellInWorld: [pos, orient]], eachTile: CheckTileValue, skip: neverInTesselation ]; }; ENDCASE } }; -- CheckArea nodeOrConstraintAtCorner: REF _ NIL; FOR rL: Rules _ task.rules, rL.rest WHILE rL#NIL DO rule: Rule = rL.first; bitIndex: ARRAY Quadrants OF INTEGER = [8, 4, 2, 1]; quadBits: INTEGER _ 0; nodeOrConstraintAtCorner _ NIL; FOR q: Quadrants IN Quadrants DO IF quadVals[q]=NIL THEN { IF rule.isStuff[spaceConstraintIndex] THEN quadBits _ quadBits + bitIndex[q] } ELSE WITH quadVals[q] SELECT FROM cc: Constraint => { IF rule.isStuff[cc.index] THEN { quadBits _ quadBits + bitIndex[q]; IF nodeOrConstraintAtCorner=NIL THEN nodeOrConstraintAtCorner _ cc } }; ENDCASE => { IF rule.isStuff[nodeConstraintIndex] THEN { quadBits _ quadBits + bitIndex[q]; nodeOrConstraintAtCorner _ quadVals[q]; }; }; ENDLOOP; SELECT quadBits FROM 0 => NULL; 1 => CheckArea[rule, rotate90, convex]; 2 => CheckArea[rule, original, convex]; 3 => NULL; 4 => CheckArea[rule, rotate270, convex]; 5 => {CheckArea[rule, rotate90, convex]; CheckArea[rule, rotate270, convex]}; 6 => NULL; 7 => CheckArea[rule, original, concave]; 8 => CheckArea[rule, rotate180, convex]; 9 => NULL; 10 => {CheckArea[rule, original, convex]; CheckArea[rule, rotate180, convex]}; 11 => CheckArea[rule, rotate90, concave]; 12 => NULL; 13 => CheckArea[rule, rotate180, concave]; 14 => CheckArea[rule, rotate270, concave]; 15 => NULL; ENDCASE => ERROR; ENDLOOP; }; -- CheckCorner IF task.geometry.stopFlag^ THEN ERROR stopped; IF task.restrict=NIL OR CStitching.FindTile[task.restrict, [x: r.x1, y: r.y1]].value#task.skipThese THEN { IF tile.SW.SEdge[] = r.y1 THEN { IF tile.WS.WEdge[]#r.x1 THEN { IF tile.value=tile.SW.value THEN CD.Error[ec: other, explanation: "tile violates horz rule"]; CheckCorner[[ne: tile.value, nw: tile.SW.value, sw: tile.WS.value, se: tile.WS.value], [r.x1, r.y1]]; } } ELSE { -- CStitching.WEdge[CStitching.WS[tile]] = r.x1 IMPLICITLY IF tile.value=tile.WS.value THEN { CheckCorner[[ne: tile.value, nw: tile.SW.value, sw: tile.SW.value, se: tile.WS.value], [r.x1, r.y1]]; } } }; IF task.restrict=NIL OR CStitching.FindTile[task.restrict, [x: r.x2, y: r.y2]].value#task.skipThese THEN { IF tile.NE.NEdge[]=r.y2 THEN { IF tile.EN.EEdge[]=r.x2 THEN { neQTile: CStitching.Tile _ tile.EN.NE; WHILE neQTile.SEdge > r.y2 DO neQTile _ neQTile.WS[] ENDLOOP; CheckCorner[[ne: neQTile.value, nw: tile.EN.value, sw: tile.value, se: tile.NE.value], [r.x2, r.y2]]; } ELSE { IF tile.value = tile.NE.value THEN CD.Error[ec: other, explanation: "tile violates max horz rule NEast"]; CheckCorner[[ne: tile.EN.value, nw: tile.EN.value, sw: tile.value, se: tile.NE.value], [r.x2, r.y2]]; } } ELSE { -- tile.EN.EEdge = r.x2 IMPLICITLY IF tile.value#tile.EN.value THEN { CheckCorner[[ne: tile.NE.value, nw: tile.EN.value, sw: tile.value, se: tile.NE.value], [r.x2, r.y2]]; } } } }; --CheckOneTile END. θCornerBasedDRCImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Redesign of some spinifex internals, originaly from Mark Shand Created by Christian Jacobi, December 13, 1985 11:06:49 am PST Last edited by: Christian Jacobi, December 2, 1986 5:59:25 pm PST -- Check if it really is an error. --CheckArea -- Optimize purely local checks. -- CheckCorner -- Translate the quadrant contents into bit vector values. -- Is this really a corner in the terms of this rule? -- Bits are ne=8, nw=4, sw=2, se=1. -- The check is applied to the quad opposite the generating corner. (IE rot. 180) -- X=TRUE, O=FALSE 0 - OO 1 - OO 2 - OO 3 - OO OO OX XO XX 4 - XO 5 - XO 6 - XO 7 - XO OO OX XO XX 8 - OX 9 - OX 10- OX 11- OX OO OX XO XX 12- XX 13- XX 14- XX 15- XX OO OX XO XX -- SW corner -- Get the quadrants at the SW corner -- ELSE NULL; a (probably rare) 4 way corner; handled at the NE corner. -- Get the quadrants at the SW corner -- ELSE NULL; No corner really -- NE corner -- 4 way corner -- Get the quadrants at the NE corner -- NE corner --ELSE NULL; No corner really Κ §˜code™Kšœ Οmœ1™Kšœ;Οk™>KšœA™A—K˜šž ˜ Kšœ˜Kšžœ˜Kšœ ˜ Kšœ˜Kšœ ˜ Kšœ˜—K˜šΟnœžœž˜!Kšžœžœ˜ Kšžœ˜—Kšž˜Kšžœ˜K˜Kšœ žœ˜#K˜šΠbn œ˜Kšœ˜—K˜š œ˜/Kšžœžœ˜Kšœ˜—K˜Kš œžœžœžœžœ˜=Kšœ žœžœ˜K˜š Ÿœžœžœžœžœ ˜9Kš žœžœžœžœžœžœ˜JKšžœžœžœ/˜OKšžœ žœžœ˜1KšœŠžœ ˜›Kšžœžœ˜Kšœ˜—K˜š œžœžœžœžœžœžœžœžœžœ˜—šžœ˜ Kšœ ž˜Kšœ7˜7Kšœ˜—Kšœ˜—K˜š  œ˜%Kšœžœ žœ˜!Kšœžœ˜#K˜šŸ œžœ žœ žœžœžœžœ˜NK˜šŸ œžœžœ.˜UK˜š œ˜'Kšœ-˜-Kšœ˜—K˜š Ÿ œžœ žœžœžœ ˜4šžœžœžœ˜Kšžœ%žœžœ˜3K˜—šžœžœžœž˜šœ˜Kšžœžœžœ˜'š žœžœžœžœFžœ˜…Kšžœ˜—K˜—šžœ˜ Kšžœ$žœžœ˜2š žœžœžœžœCžœ˜‚Kšžœ˜—K˜——KšΟc"™"Kšžœžœžœ˜šžœžœžœ˜šžœ˜Kšœ˜Kšœk˜kKšœ˜Kšœžœžœ˜—K˜—šœ ˜ Kšœ ˜ Kšœ ˜ Kšœn˜nKšœ˜—Kšœž˜Kšœ‘ ˜—K˜Kšœ ™ Kšœžœžœ˜Kšœžœ˜Kšœžœ˜šžœ žœ˜Kš‘ ™ šžœž˜KšœC˜C—šžœž˜KšœC˜C—šžœž˜KšœC˜C—šžœž˜KšœC˜C—K˜—šžœ˜šžœ ž˜˜ šœ˜Kšœ˜Kšœg˜gKšœ˜Kšœ˜Kšœ˜—šœ˜Kšœ˜Kšœe˜eKšœ˜Kšœ˜Kšœ˜—K˜—šœ ˜ šœ˜Kšœ˜Kšœb˜bKšœ˜Kšœ˜Kšœ˜—K˜—Kšž˜—K˜—Kšœ‘Πce ˜—K˜Kš‘™Kšœžœžœ˜$šžœ!žœžœž˜3Kšœ˜Kšœ žœ žœžœ˜4Kšœ žœ˜Kšœžœ˜Kš‘:™:šžœžœ ž˜ šžœ žœžœ˜Kšžœ$žœ"˜LK˜—šžœžœ žœž˜!šœ˜šžœžœ˜ Kšœ"˜"Kšžœžœžœ˜BK˜—K˜—šžœ˜ šžœ#žœ˜+Kšœ"˜"Kšœ'˜'K˜—Kšœ˜——Kšžœ˜ —Kš‘5™5Kš‘%™%Kš‘R™RKšA‘ΟfΠfk£ €£ €£ €£€£ €£ €£ €£€£ €£ €£ €£€£ €£ €£ €£€£ €£ €£ €£€£ €£ €£ €£€£ €£ €£ €£€£ €£ €£ €™Υšžœ ž˜Kšœžœ˜ Kšœ(˜(Kšœ(˜(Kšœžœ˜ Kšœ)˜)KšœN˜NKšœžœ˜ Kšœ)˜)Kšœ)˜)Kšœžœ˜ KšœN˜NKšœ)˜)Kšœžœ˜ Kšœ*˜*Kšœ*˜*Kšœžœ˜ Kšžœžœ˜—Kšžœ˜—Kšœ‘’ ˜K˜K˜—Kš‘ ™ Kšžœžœžœ ˜/šžœžœžœMžœ˜jšžœžœžœ˜ šžœžœžœ˜šžœžœžœ˜!Kšžœ:˜<—Kš‘%™%Kšœ&žœžœžœ˜eKšœ˜—Kš‘G™GK˜—šžœ‘:˜Ašžœžœžœ˜"Kš‘%™%Kšœ&žœžœžœ˜eK˜—Kš‘™K˜—K˜—Kš‘ ™ šžœžœžœMžœ˜jšžœžœžœ˜šžœžœžœ˜Kš‘™Kšœ žœžœ˜&Kšžœžœžœžœ˜=Kšœ)žœ!žœ˜eK˜—šžœ˜šžœžœžœ˜#KšžœD˜F—Kš‘%™%Kšœžœžœ!žœ˜eK˜—K˜—šžœ‘"˜)šžœžœžœ˜"Kš‘ ™ Kšœžœžœ!žœ˜eK˜—Kš‘™K˜—K˜—Kšœ‘˜K˜—Kšžœ˜K˜—…—'