From 75a18053f87e213294e7ec4334ff3f1ed322d5af Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Thu, 12 Nov 2020 10:34:27 -0500 Subject: [PATCH] Modified the CIFGenLayer() routine to be aware of when it is called during hierarchical processing from CIFGenSubcells() and CIFGenArrays(), and to avoid certain operators that are useless and harmful when applied hierarchically; namely squares, slots, bbox, boundary, and net. --- VERSION | 2 +- calma/CalmaWrite.c | 6 +++- cif/CIFgen.c | 44 ++++++++++++++++++++++++++++-- cif/CIFhier.c | 68 ++++++++++++++++++++++++++++++++++++++++------ cif/CIFrdcl.c | 3 +- cif/CIFsee.c | 9 ++++-- cif/CIFtech.c | 7 +++++ cif/CIFwrite.c | 3 +- drc/DRCcif.c | 2 +- graphics/W3Dmain.c | 3 +- 10 files changed, 127 insertions(+), 20 deletions(-) diff --git a/VERSION b/VERSION index 3d73f92b..896df0cf 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.80 +8.3.81 diff --git a/calma/CalmaWrite.c b/calma/CalmaWrite.c index 2118c18a..41732d23 100644 --- a/calma/CalmaWrite.c +++ b/calma/CalmaWrite.c @@ -799,6 +799,9 @@ calmaProcessDef(def, outf, do_library) if (isReadOnly && hasContent && CalmaAddendum) return (0); + /* Give some feedback to the user */ + TxPrintf(" Writing cell %s\n", def->cd_name); + /* * Output the definitions for any of our descendants that have * not already been output. Numbers are assigned to the subcells @@ -1008,7 +1011,8 @@ calmaOutFunc(def, f, cliprect) /* Output all the tiles associated with this cell; skip temporary layers */ GEO_EXPAND(&def->cd_bbox, CIFCurStyle->cs_radius, &bigArea); CIFErrorDef = def; - CIFGen(def, def, &bigArea, CIFPlanes, &DBAllTypeBits, TRUE, TRUE, (ClientData) f); + CIFGen(def, def, &bigArea, CIFPlanes, &DBAllTypeBits, TRUE, TRUE, FALSE, + (ClientData)f); if (!CIFHierWriteDisable) CIFGenSubcells(def, &bigArea, CIFPlanes); if (!CIFArrayWriteDisable) diff --git a/cif/CIFgen.c b/cif/CIFgen.c index 938729be..8321da85 100644 --- a/cif/CIFgen.c +++ b/cif/CIFgen.c @@ -4656,7 +4656,7 @@ cifBridgeLimFunc2(tile, brlims) */ Plane * -CIFGenLayer(op, area, cellDef, origDef, temps, clientdata) +CIFGenLayer(op, area, cellDef, origDef, temps, hier, clientdata) CIFOp *op; /* List of CIFOps telling how to make layer. */ Rect *area; /* Area to consider when generating CIF. Only * material in this area will be considered, so @@ -4672,6 +4672,7 @@ CIFGenLayer(op, area, cellDef, origDef, temps, clientdata) Plane *temps[]; /* Temporary layers to be used when needed * for operation. */ + bool hier; /* TRUE if called from CIFGenSubcell or CIFGenArray */ ClientData clientdata; /* * Data that may be passed to the CIF operation * function. @@ -4689,6 +4690,7 @@ CIFGenLayer(op, area, cellDef, origDef, temps, clientdata) BridgeStruct brs; BridgeLimStruct brlims; BridgeData *bridge; + bool hstop = FALSE; int (*cifGrowFuncPtr)() = (CIFCurStyle->cs_flags & CWF_GROW_EUCLIDEAN) ? cifGrowEuclideanFunc : cifGrowFunc; @@ -4703,6 +4705,10 @@ CIFGenLayer(op, area, cellDef, origDef, temps, clientdata) /* Go through the geometric operations and process them one * at a time. + * + * NOTE: Some opcodes (and whatever follows them) should never + * be run during hierarchical processing. That includes BOUNDARY, + * SQUARES/SLOTS, BBOX, and NET. */ for ( ; op != NULL; op = op->co_next) @@ -4961,6 +4967,11 @@ CIFGenLayer(op, area, cellDef, origDef, temps, clientdata) break; case CIFOP_SQUARES: + if (hier) + { + hstop = TRUE; /* Stop hierarchical processing */ + break; + } if (CalmaContactArrays == FALSE) { DBClearPaintPlane(nextPlane); @@ -4973,6 +4984,11 @@ CIFGenLayer(op, area, cellDef, origDef, temps, clientdata) break; case CIFOP_SQUARES_G: + if (hier) + { + hstop = TRUE; /* Stop hierarchical processing */ + break; + } DBClearPaintPlane(nextPlane); cifPlane = nextPlane; cifSquaresFillArea(op, cellDef, curPlane); @@ -4982,6 +4998,11 @@ CIFGenLayer(op, area, cellDef, origDef, temps, clientdata) break; case CIFOP_SLOTS: + if (hier) + { + hstop = TRUE; /* Stop hierarchical processing */ + break; + } DBClearPaintPlane(nextPlane); cifPlane = nextPlane; cifSlotsFillArea(op, cellDef, curPlane); @@ -5002,6 +5023,11 @@ CIFGenLayer(op, area, cellDef, origDef, temps, clientdata) break; case CIFOP_NET: + if (hier) + { + hstop = TRUE; /* Stop hierarchical processing */ + break; + } netname = (char *)op->co_client; cifPlane = curPlane; ttype = CmdFindNetProc(netname, CIFDummyUse, &bbox, FALSE); @@ -5022,6 +5048,11 @@ CIFGenLayer(op, area, cellDef, origDef, temps, clientdata) break; case CIFOP_BOUNDARY: + if (hier) + { + hstop = TRUE; /* Stop hierarchical processing */ + break; + } cifPlane = curPlane; /* This function for cifoutput only. cifinput handled separately. */ @@ -5047,6 +5078,11 @@ CIFGenLayer(op, area, cellDef, origDef, temps, clientdata) break; case CIFOP_BBOX: + if (hier) + { + hstop = TRUE; /* Stop hierarchical processing */ + break; + } if (CIFErrorDef == NULL) break; /* co_client contains the flag (1) for top-level only */ @@ -5084,6 +5120,7 @@ CIFGenLayer(op, area, cellDef, origDef, temps, clientdata) default: continue; } + if (hstop) break; /* Don't process any further rules */ } return curPlane; @@ -5112,7 +5149,7 @@ CIFGenLayer(op, area, cellDef, origDef, temps, clientdata) */ void -CIFGen(cellDef, origDef, area, planes, layers, replace, genAllPlanes, clientdata) +CIFGen(cellDef, origDef, area, planes, layers, replace, genAllPlanes, hier, clientdata) CellDef *cellDef; /* Cell for which CIF is to be generated. */ CellDef *origDef; /* Original cell, if different from cellDef */ Rect *area; /* Any CIF overlapping this area (in coords @@ -5135,6 +5172,7 @@ CIFGen(cellDef, origDef, area, planes, layers, replace, genAllPlanes, clientdata * those layers not specified as being * generated in the 'layers' mask above. */ + bool hier; /* TRUE if called from CIFGenSubcell or CIFGenArray */ ClientData clientdata; /* Data that may be passed along to the * CIF operation functions. */ @@ -5160,7 +5198,7 @@ CIFGen(cellDef, origDef, area, planes, layers, replace, genAllPlanes, clientdata { CIFErrorLayer = i; new[i] = CIFGenLayer(CIFCurStyle->cs_layers[i]->cl_ops, - &expanded, cellDef, origDef, new, clientdata); + &expanded, cellDef, origDef, new, hier, clientdata); /* Clean up the non-manhattan geometry in the plane */ if (CIFUnfracture) DBMergeNMTiles(new[i], &expanded, diff --git a/cif/CIFhier.c b/cif/CIFhier.c index d5afda0e..4759862c 100644 --- a/cif/CIFhier.c +++ b/cif/CIFhier.c @@ -27,6 +27,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/ #include +#include "tcltk/tclmagic.h" #include "utils/magic.h" #include "utils/geometry.h" #include "tiles/tile.h" @@ -35,6 +36,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/ #include "cif/CIFint.h" #include "cif/cif.h" #include "drc/drc.h" +#include "graphics/graphics.h" #include "textio/textio.h" #include "utils/undo.h" #include "utils/malloc.h" @@ -326,7 +328,8 @@ cifHierCellFunc(scx) CIFErrorDef = (CellDef *) NULL; GeoTransRect(&scx->scx_trans, &scx->scx_area, &rootArea); CIFGen(CIFComponentDef, scx->scx_use->cu_def, &rootArea, - CIFComponentPlanes, &CIFCurStyle->cs_hierLayers, FALSE, TRUE); + CIFComponentPlanes, &CIFCurStyle->cs_hierLayers, FALSE, + TRUE, TRUE, (ClientData)NULL); return 0; } @@ -523,6 +526,8 @@ CIFGenSubcells(def, area, output) int stepSize, x, y, i, radius, oldTileOps, oldTileOps2; Rect totalArea, square, interaction; SearchContext scx; + int cuts, totcuts; + float pdone, plast; UndoDisable(); CIFInitCells(); @@ -537,6 +542,16 @@ CIFGenSubcells(def, area, output) scx.scx_use = CIFDummyUse; scx.scx_trans = GeoIdentityTransform; + /* This routine can take a long time, so use the display + * timer to force a 5-second progress check (like is done + * with extract) + */ + GrDisplayStatus = DISPLAY_IN_PROGRESS; + SigSetTimer(5); /* Print at 5-second intervals */ + cuts = 0; + pdone = 0.0; + plast = 0.0; + /* Any tile operations processed here get billed to hierarchy * in addition to being added to the total. */ @@ -551,6 +566,12 @@ CIFGenSubcells(def, area, output) totalArea = *area; GeoClip(&totalArea, &def->cd_bbox); + + totcuts = (totalArea.r_ytop - totalArea.r_ybot + stepSize - 1) + / stepSize; + totcuts *= ((totalArea.r_xtop - totalArea.r_xbot + stepSize - 1) + / stepSize); + for (y = totalArea.r_ybot; y < totalArea.r_ytop; y += stepSize) for (x = totalArea.r_xbot; x < totalArea.r_xtop; x += stepSize) { @@ -576,7 +597,8 @@ CIFGenSubcells(def, area, output) cifHierCopyFunc, (ClientData) CIFTotalDef); CIFErrorDef = def; CIFGen(CIFTotalDef, def, &interaction, CIFTotalPlanes, - &CIFCurStyle->cs_hierLayers, TRUE, TRUE); + &CIFCurStyle->cs_hierLayers, TRUE, TRUE, TRUE, + (ClientData)NULL); /* Now go through all the subcells overlapping the area * and generate CIF for each subcell individually. OR this @@ -593,7 +615,8 @@ CIFGenSubcells(def, area, output) CIFErrorDef = (CellDef *) NULL; CIFGen(def, def, &interaction, CIFComponentPlanes, - &CIFCurStyle->cs_hierLayers, FALSE, TRUE); + &CIFCurStyle->cs_hierLayers, FALSE, TRUE, TRUE, + (ClientData)NULL); /* Make sure everything in the pieces is also in the overall * CIF, then erase the piece stuff from the overall, and @@ -618,9 +641,33 @@ CIFGenSubcells(def, area, output) CIFHierRects += CIFTileOps - oldTileOps2; cifHierCleanup(); + + cuts++; + pdone = 100.0 * ((float)cuts / (float)totcuts); + if ((((pdone - plast) > 1.0) || (cuts == totcuts)) && (cuts > 1)) + { + /* Only print something if the 5-second timer has expired */ + if (GrDisplayStatus == DISPLAY_BREAK_PENDING) + { + TxPrintf("Completed %d%%\n", (int)(pdone + 0.5)); + plast = pdone; + TxFlushOut(); + + GrDisplayStatus = DISPLAY_IN_PROGRESS; + SigSetTimer(5); + } +#ifdef MAGIC_WRAPPER + /* We need to let Tk paint the console display */ + while (Tcl_DoOneEvent(TCL_DONT_WAIT) != 0); +#endif + } } CIFHierTileOps += CIFTileOps - oldTileOps; + + GrDisplayStatus = DISPLAY_IDLE; + SigRemoveTimer(); + UndoEnable(); } @@ -680,7 +727,8 @@ cifHierElementFunc(use, transform, x, y, checkArea) CIFErrorDef = (CellDef *) NULL; CIFGen(CIFComponentDef, use->cu_def, checkArea, CIFComponentPlanes, - &CIFCurStyle->cs_hierLayers, FALSE, TRUE); + &CIFCurStyle->cs_hierLayers, FALSE, TRUE, TRUE, + (ClientData)NULL); return 0; } @@ -921,7 +969,8 @@ cifHierArrayFunc(scx, output) (ClientData) &A); CIFErrorDef = use->cu_parent; CIFGen(CIFTotalDef, use->cu_def, &A, CIFTotalPlanes, - &CIFCurStyle->cs_hierLayers, FALSE, TRUE); + &CIFCurStyle->cs_hierLayers, FALSE, TRUE, TRUE, + (ClientData)NULL); anyInteractions = TRUE; } @@ -938,7 +987,8 @@ cifHierArrayFunc(scx, output) (ClientData) &C); CIFErrorDef = use->cu_parent; CIFGen(CIFTotalDef, use->cu_def, &C, CIFTotalPlanes, - &CIFCurStyle->cs_hierLayers, FALSE, TRUE); + &CIFCurStyle->cs_hierLayers, FALSE, TRUE, TRUE, + (ClientData)NULL); anyInteractions = TRUE; } @@ -955,7 +1005,8 @@ cifHierArrayFunc(scx, output) (ClientData) &B); CIFErrorDef = use->cu_parent; CIFGen(CIFTotalDef, use->cu_def, &B, CIFTotalPlanes, - &CIFCurStyle->cs_hierLayers, FALSE, TRUE); + &CIFCurStyle->cs_hierLayers, FALSE, TRUE, TRUE, + (ClientData)NULL); /* D */ @@ -968,7 +1019,8 @@ cifHierArrayFunc(scx, output) (ClientData) &D); CIFErrorDef = use->cu_parent; CIFGen(CIFTotalDef, use->cu_def, &D, CIFTotalPlanes, - &CIFCurStyle->cs_hierLayers, FALSE, TRUE); + &CIFCurStyle->cs_hierLayers, FALSE, TRUE, TRUE, + (ClientData)NULL); } if (anyInteractions) diff --git a/cif/CIFrdcl.c b/cif/CIFrdcl.c index 02114afb..10dd823a 100644 --- a/cif/CIFrdcl.c +++ b/cif/CIFrdcl.c @@ -572,7 +572,8 @@ CIFPaintCurrent(filetype) CIFOp *op; plane = CIFGenLayer(cifCurReadStyle->crs_layers[i]->crl_ops, - &TiPlaneRect, (CellDef *)NULL, (CellDef *)NULL, cifCurReadPlanes); + &TiPlaneRect, (CellDef *)NULL, (CellDef *)NULL, + cifCurReadPlanes, FALSE, (ClientData)NULL); /* Generate a paint/erase table, then paint from the CIF * plane into the current Magic cell. diff --git a/cif/CIFsee.c b/cif/CIFsee.c index 4b880266..e450e003 100644 --- a/cif/CIFsee.c +++ b/cif/CIFsee.c @@ -164,7 +164,8 @@ CIFPaintLayer(rootDef, area, cifLayer, magicLayer, paintDef) cifHierCopyFunc, (ClientData) CIFComponentDef); oldCount = DBWFeedbackCount; - CIFGen(CIFComponentDef, rootDef, area, CIFPlanes, &depend, TRUE, TRUE); + CIFGen(CIFComponentDef, rootDef, area, CIFPlanes, &depend, TRUE, TRUE, FALSE, + (ClientData)NULL); DBCellClearDef(CIFComponentDef); /* Report any errors that occurred. */ @@ -278,7 +279,8 @@ CIFSeeLayer(rootDef, area, layer) (void) DBTreeSrTiles(&scx, &DBAllButSpaceAndDRCBits, 0, cifHierCopyFunc, (ClientData) CIFComponentDef); oldCount = DBWFeedbackCount; - CIFGen(CIFComponentDef, rootDef, area, CIFPlanes, &depend, TRUE, TRUE); + CIFGen(CIFComponentDef, rootDef, area, CIFPlanes, &depend, TRUE, TRUE, + FALSE, (ClientData)NULL); DBCellClearDef(CIFComponentDef); /* Report any errors that occurred. */ @@ -441,7 +443,8 @@ CIFCoverageLayer(rootDef, area, layer) scx.scx_trans = GeoIdentityTransform; (void) DBTreeSrTiles(&scx, &DBAllButSpaceAndDRCBits, 0, cifHierCopyFunc, (ClientData) CIFComponentDef); - CIFGen(CIFComponentDef, rootDef, area, CIFPlanes, &depend, TRUE, TRUE); + CIFGen(CIFComponentDef, rootDef, area, CIFPlanes, &depend, TRUE, TRUE, + FALSE, (ClientData)NULL); DBCellClearDef(CIFComponentDef); cstats.coverage = 0; diff --git a/cif/CIFtech.c b/cif/CIFtech.c index 07343f05..ce939289 100644 --- a/cif/CIFtech.c +++ b/cif/CIFtech.c @@ -1537,6 +1537,12 @@ cifComputeRadii(layer, des) for (op = layer->cl_ops; op != NULL; op = op->co_next) { + /* BBOX and NET operators should never be used hierarchically */ + /* so ignore any grow/shrink operators that come after them. */ + + if (op->co_opcode == CIFOP_BBOX || op->co_opcode == CIFOP_NET) + break; + /* If CIF layers are used, switch to the max of current * distances and those of the layers used. */ @@ -1597,6 +1603,7 @@ cifComputeRadii(layer, des) case CIFOP_BRIDGELIM: break; case CIFOP_SQUARES: break; case CIFOP_SQUARES_G: break; + } } diff --git a/cif/CIFwrite.c b/cif/CIFwrite.c index 558f147c..8f40c2b2 100644 --- a/cif/CIFwrite.c +++ b/cif/CIFwrite.c @@ -378,7 +378,8 @@ cifOutFunc(def, f) GEO_EXPAND(&def->cd_bbox, CIFCurStyle->cs_radius, &bigArea); CIFErrorDef = def; - CIFGen(def, def, &bigArea, CIFPlanes, &DBAllTypeBits, TRUE, TRUE); + CIFGen(def, def, &bigArea, CIFPlanes, &DBAllTypeBits, TRUE, TRUE, FALSE, + (ClientData)NULL); if (!CIFHierWriteDisable) CIFGenSubcells(def, &bigArea, CIFPlanes); if (!CIFArrayWriteDisable) diff --git a/drc/DRCcif.c b/drc/DRCcif.c index c280c4bd..a06d8d0d 100644 --- a/drc/DRCcif.c +++ b/drc/DRCcif.c @@ -552,7 +552,7 @@ drcCifCheck(arg) oldTiles = DRCstatTiles; CIFGen(arg->dCD_celldef, arg->dCD_celldef, checkRect, CIFPlanes, - &DBAllTypeBits, TRUE, TRUE); + &DBAllTypeBits, TRUE, TRUE, FALSE, (ClientData)NULL); for (i = 0; i < drcCifStyle->cs_nLayers; i++) { diff --git a/graphics/W3Dmain.c b/graphics/W3Dmain.c index 656f37b8..ec77baf3 100644 --- a/graphics/W3Dmain.c +++ b/graphics/W3Dmain.c @@ -1739,7 +1739,8 @@ W3DCIFredisplay(w, rootArea, clipArea) scx.scx_trans = GeoIdentityTransform; (void) DBTreeSrTiles(&scx, &DBAllButSpaceAndDRCBits, 0, cifHierCopyFunc, (ClientData) CIFComponentDef); - CIFGen(CIFComponentDef, cellDef, &clipRect, CIFPlanes, &DBAllTypeBits, TRUE, TRUE); + CIFGen(CIFComponentDef, cellDef, &clipRect, CIFPlanes, &DBAllTypeBits, TRUE, + TRUE, FALSE, (ClientData)NULL); DBCellClearDef(CIFComponentDef); w3dClear();