RootInst:
PROC [fused: HashTable.Table, inst:
CD.Instance]
RETURNS [root:
CD.Instance] = {
IF inst=NIL THEN ERROR;
root ← NARROW [HashTable.Fetch[fused, inst].value];
IF root=NIL THEN RETURN [inst];
IF root=inst THEN ERROR;
root ← RootInst[fused, root];
[] ← HashTable.Replace[fused, inst, root];
};
ToRoutingCell:
PROC [old:
CD.Object]
RETURNS [new:
CD.Object] = {
plane: CStitching.Tesselation ← CStitching.NewTesselation[];
fused: HashTable.Table ← HashTable.Create[]; -- Fisher Galler table pointing instances to their father
rootInsts: HashTable.Table ← HashTable.Create[]; -- Table root instance -> other instances fused to it
nodes: LIST OF PWObjects.Node ← NIL;
nodesNb: INT ← 0;
name: ROPE = CDDirectory.Name[old];
AddInst: CDCells.InstEnumerator = {
Fuse: CStitching.TileProc = {
oldInst: CD.Instance ← NARROW [tile.value];
oldInst ← RootInst[fused, oldInst];
IF oldInst=inst THEN RETURN;
IF NOT Touch[oldInst, inst] THEN RETURN;
[] ← HashTable.Store[fused, oldInst, inst];
tile.value ← inst;
};
IF CDTexts.IsText[inst.ob] THEN {TerminalIO.PutF["Discarded text %g.\n", IO.rope[NARROW [inst.ob.specific, CDTexts.TextSpecific].text]]; RETURN};
CStitching.EnumerateArea[plane, CDInstances.InstRectO[inst], Fuse];
};
AddRootInst: CDCells.InstEnumerator = {
IF CDTexts.IsText[inst.ob] THEN RETURN;
IF RootInst[fused, inst]=inst THEN [] ← HashTable.Store[rootInsts, inst, NIL];
};
AddFusedInst: HashTable.EachPairAction = {
fusedInst: CD.Instance ← NARROW [key];
root: CD.Instance ← RootInst[fused, NARROW [value]];
insts: LIST OF CD.Instance;
IF fusedInst=root THEN ERROR;
insts ← NARROW [HashTable.Fetch[rootInsts, root].value];
IF NOT GList.Member[fusedInst, insts] THEN insts ← CONS [fusedInst, insts];
[] ← HashTable.Store[rootInsts, root, insts];
};
MakeNode: HashTable.EachPairAction = {
root: CD.Instance ← NARROW [key];
insts: LIST OF CD.Instance ← NARROW [value];
geometry: LIST OF PWObjects.PlacedObject ← NIL;
FOR list:
LIST
OF
CD.Instance ←
CONS [root, insts], list.rest
WHILE list#
NIL
DO
instance: CD.Instance ← list.first;
object: CD.Object = CachedRotate[instance.ob, instance.trans.orient];
geometry ←
CONS [
[object: object, position: CDBasics.BaseOfRect[CDInstances.InstRectO[instance]]],
geometry
];
ENDLOOP;
nodes ← CONS [PWObjects.CreateNode[geometry], nodes];
nodesNb ← nodesNb + 1;
};
We flatten!
old ← PW.Flatten[old];
We create the corner stitch
[] ← CDCells.EnumerateInstances[old, AddInst];
Let's release some space!
CStitching.ResetTesselation[plane];
We compute rootInsts by first putting all roots in the table
[] ← CDCells.EnumerateInstances[old, AddRootInst];
We add in rootInsts all the fused ones
[] ← HashTable.Pairs[fused, AddFusedInst];
We make node, now
[] ← HashTable.Pairs[rootInsts, MakeNode];
The final cell
new ← PWObjects.CreateRouting[CD.InterestRect[old], nodes];
TerminalIO.PutF["Object %g translated to routing: %g nodes.\n", IO.rope[name], IO.int[nodesNb]];
};