From 3203eec28cb14ff6e1453e44b094322a7d3fddd5 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Tue, 26 May 2020 14:29:36 -0400 Subject: [PATCH] Modified the "bloat-all" cifoutput operator to allow operations on templayers. This permits some useful interactions like growing to the size of a bounding box, or abutment box, as well as many other possibilities. Also: Corrected the use of "cif see" for the boundary (abutment box) layer, which was not working because the "cif see" command uses a flattened CellDef that does not have the boundary property of the cell it was flattened from. --- VERSION | 2 +- calma/CalmaWrite.c | 2 +- cif/CIFgen.c | 64 +++++++++++++++++++++++++++++++++++++--------- cif/CIFhier.c | 28 ++++++++++---------- cif/CIFint.h | 1 + cif/CIFmain.c | 16 ++++++++++++ cif/CIFrdcl.c | 2 +- cif/CIFsee.c | 7 ++--- cif/CIFtech.c | 52 ++++++++++++++++++++++++++----------- cif/CIFwrite.c | 2 +- drc/DRCcif.c | 3 ++- graphics/W3Dmain.c | 2 +- 12 files changed, 131 insertions(+), 50 deletions(-) diff --git a/VERSION b/VERSION index 805e01a3..be5a9bbb 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.15 +8.3.16 diff --git a/calma/CalmaWrite.c b/calma/CalmaWrite.c index a02a3d8c..4ef116c3 100644 --- a/calma/CalmaWrite.c +++ b/calma/CalmaWrite.c @@ -998,7 +998,7 @@ 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, &bigArea, CIFPlanes, &DBAllTypeBits, TRUE, TRUE, (ClientData) f); + CIFGen(def, def, &bigArea, CIFPlanes, &DBAllTypeBits, TRUE, TRUE, (ClientData) f); if (!CIFHierWriteDisable) CIFGenSubcells(def, &bigArea, CIFPlanes); if (!CIFArrayWriteDisable) diff --git a/cif/CIFgen.c b/cif/CIFgen.c index 7ed4549a..cd2173fd 100644 --- a/cif/CIFgen.c +++ b/cif/CIFgen.c @@ -1051,6 +1051,7 @@ cifFoundFunc(tile, BloatStackPtr) typedef struct _bloatStruct { CIFOp *op; CellDef *def; + Plane **temps; } BloatStruct; /* @@ -1080,21 +1081,24 @@ cifBloatAllFunc(tile, bls) Rect area; TileTypeBitMask connect; Tile *t, *tp; - TileType type; + TileType type, ttype; BloatData *bloats; int i, locScale; PlaneMask pmask; CIFOp *op; CellDef *def; + Plane **temps; static Stack *BloatStack = (Stack *)NULL; op = bls->op; def = bls->def; + temps = bls->temps; bloats = (BloatData *)op->co_client; /* Create a mask of all connecting types (these must be in a single * plane), then call a search function to find all connecting material - * of these types. + * of these types (if the bloat types are temp layers, then this mask + * is not used). */ TTMaskZero(&connect); @@ -1117,7 +1121,10 @@ cifBloatAllFunc(tile, bls) if (type == CIF_SOLIDTYPE) { pmask = 0; - locScale = (CIFCurStyle) ? CIFCurStyle->cs_scaleFactor : 1; + if (bloats->bl_isCif == TRUE) + locScale = 1; + else + locScale = (CIFCurStyle) ? CIFCurStyle->cs_scaleFactor : 1; /* Get the tile into magic database coordinates if it's in CIF coords */ TiToRect(tile, &area); @@ -1129,13 +1136,40 @@ cifBloatAllFunc(tile, bls) else { int pNum = DBPlane(type); - pmask = CoincidentPlanes(&connect, PlaneNumToMaskBit(pNum)); + pmask = (bloats->bl_isCif == TRUE) ? 0 : + CoincidentPlanes(&connect, PlaneNumToMaskBit(pNum)); if (pmask == 0) TiToRect(tile, &area); - locScale = cifScale; + if (bloats->bl_isCif == TRUE) + { + /* Get the tile into CIF database coordinates if it's in magic coords */ + area.r_xbot *= cifScale; + area.r_xtop *= cifScale; + area.r_ybot *= cifScale; + area.r_ytop *= cifScale; + locScale = 1; + } + else + { + locScale = cifScale; + } } if (pmask == 0) - DBSrPaintArea((Tile *)NULL, def->cd_planes[bloats->bl_plane], &area, - &connect, cifFoundFunc, (ClientData)(&BloatStack)); + { + if (bloats->bl_isCif) + { + /* This expands the area to the OR of all temp layers specified */ + /* which may or may not be useful; normally one would expand */ + /* into a single layer if a temp layer is specified. */ + + for (ttype = 0; ttype < TT_MAXTYPES; ttype++, temps++) + if (bloats->bl_distance[ttype] > 0) + (void) DBSrPaintArea((Tile *)NULL, *temps, &area, + &CIFSolidBits, cifFoundFunc, (ClientData)(&BloatStack)); + } + else + DBSrPaintArea((Tile *)NULL, def->cd_planes[bloats->bl_plane], &area, + &connect, cifFoundFunc, (ClientData)(&BloatStack)); + } else PUSHTILE(t, BloatStack); @@ -3127,7 +3161,7 @@ cifSrTiles(cifOp, area, cellDef, temps, func, cdArg) */ Plane * -CIFGenLayer(op, area, cellDef, temps, clientdata) +CIFGenLayer(op, area, cellDef, origDef, temps, 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 @@ -3137,6 +3171,9 @@ CIFGenLayer(op, area, cellDef, temps, clientdata) CellDef *cellDef; /* CellDef to search when paint layers are * needed for operation. */ + CellDef *origDef; /* Original CellDef for which output is being + * generated (cellDef may be derived from this). + */ Plane *temps[]; /* Temporary layers to be used when needed * for operation. */ @@ -3374,6 +3411,7 @@ CIFGenLayer(op, area, cellDef, temps, clientdata) cifPlane = curPlane; bls.op = op; bls.def = cellDef; + bls.temps = temps; cifSrTiles(op, area, cellDef, temps, cifBloatAllFunc, (ClientData)&bls); break; @@ -3442,12 +3480,13 @@ CIFGenLayer(op, area, cellDef, temps, clientdata) case CIFOP_BOUNDARY: cifPlane = curPlane; /* This function for cifoutput only. cifinput handled separately. */ - if (cellDef && (cellDef->cd_flags & CDFIXEDBBOX)) + + if (origDef && (origDef->cd_flags & CDFIXEDBBOX)) { char *propvalue; bool found; - propvalue = (char *)DBPropGet(cellDef, "FIXED_BBOX", &found); + propvalue = (char *)DBPropGet(origDef, "FIXED_BBOX", &found); if (!found) break; if (sscanf(propvalue, "%d %d %d %d", &bbox.r_xbot, &bbox.r_ybot, &bbox.r_xtop, &bbox.r_ytop) != 4) break; @@ -3527,8 +3566,9 @@ CIFGenLayer(op, area, cellDef, temps, clientdata) */ void -CIFGen(cellDef, area, planes, layers, replace, genAllPlanes, clientdata) +CIFGen(cellDef, origDef, area, planes, layers, replace, genAllPlanes, 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 * of cellDef) will be generated. The CIF * will be clipped to this area. @@ -3574,7 +3614,7 @@ CIFGen(cellDef, area, planes, layers, replace, genAllPlanes, clientdata) { CIFErrorLayer = i; new[i] = CIFGenLayer(CIFCurStyle->cs_layers[i]->cl_ops, - &expanded, cellDef, new, clientdata); + &expanded, cellDef, origDef, new, 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 97d3e465..d5afda0e 100644 --- a/cif/CIFhier.c +++ b/cif/CIFhier.c @@ -316,7 +316,7 @@ cifHierCellFunc(scx) newscx = *scx; GEO_EXPAND(&scx->scx_area, CIFCurStyle->cs_radius, &newscx.scx_area); (void) DBTreeSrTiles(&newscx, &CIFCurStyle->cs_yankLayers, 0, - cifHierCopyFunc, (ClientData) CIFComponentDef); + cifHierCopyFunc, (ClientData) CIFComponentDef); /* Set CIFErrorDef to NULL to ignore errors here... these will * get reported anyway when the cell is CIF'ed non-hierarchically, @@ -325,8 +325,8 @@ cifHierCellFunc(scx) CIFErrorDef = (CellDef *) NULL; GeoTransRect(&scx->scx_trans, &scx->scx_area, &rootArea); - CIFGen(CIFComponentDef, &rootArea, CIFComponentPlanes, - &CIFCurStyle->cs_hierLayers, FALSE, TRUE); + CIFGen(CIFComponentDef, scx->scx_use->cu_def, &rootArea, + CIFComponentPlanes, &CIFCurStyle->cs_hierLayers, FALSE, TRUE); return 0; } @@ -575,7 +575,7 @@ CIFGenSubcells(def, area, output) (void) DBTreeSrTiles(&scx, &CIFCurStyle->cs_yankLayers, 0, cifHierCopyFunc, (ClientData) CIFTotalDef); CIFErrorDef = def; - CIFGen(CIFTotalDef, &interaction, CIFTotalPlanes, + CIFGen(CIFTotalDef, def, &interaction, CIFTotalPlanes, &CIFCurStyle->cs_hierLayers, TRUE, TRUE); /* Now go through all the subcells overlapping the area @@ -592,7 +592,7 @@ CIFGenSubcells(def, area, output) */ CIFErrorDef = (CellDef *) NULL; - CIFGen(def, &interaction, CIFComponentPlanes, + CIFGen(def, def, &interaction, CIFComponentPlanes, &CIFCurStyle->cs_hierLayers, FALSE, TRUE); /* Make sure everything in the pieces is also in the overall @@ -679,7 +679,7 @@ cifHierElementFunc(use, transform, x, y, checkArea) cifHierCopyFunc, (ClientData) CIFComponentDef); CIFErrorDef = (CellDef *) NULL; - CIFGen(CIFComponentDef, checkArea, CIFComponentPlanes, + CIFGen(CIFComponentDef, use->cu_def, checkArea, CIFComponentPlanes, &CIFCurStyle->cs_hierLayers, FALSE, TRUE); return 0; @@ -920,8 +920,8 @@ cifHierArrayFunc(scx, output) (void) DBArraySr(use, &expandedArea, cifHierElementFunc, (ClientData) &A); CIFErrorDef = use->cu_parent; - CIFGen(CIFTotalDef, &A, CIFTotalPlanes, &CIFCurStyle->cs_hierLayers, - FALSE, TRUE); + CIFGen(CIFTotalDef, use->cu_def, &A, CIFTotalPlanes, + &CIFCurStyle->cs_hierLayers, FALSE, TRUE); anyInteractions = TRUE; } @@ -937,8 +937,8 @@ cifHierArrayFunc(scx, output) (void) DBArraySr(use, &expandedArea, cifHierElementFunc, (ClientData) &C); CIFErrorDef = use->cu_parent; - CIFGen(CIFTotalDef, &C, CIFTotalPlanes, &CIFCurStyle->cs_hierLayers, - FALSE, TRUE); + CIFGen(CIFTotalDef, use->cu_def, &C, CIFTotalPlanes, + &CIFCurStyle->cs_hierLayers, FALSE, TRUE); anyInteractions = TRUE; } @@ -954,8 +954,8 @@ cifHierArrayFunc(scx, output) (void) DBArraySr(use, &expandedArea, cifHierElementFunc, (ClientData) &B); CIFErrorDef = use->cu_parent; - CIFGen(CIFTotalDef, &B, CIFTotalPlanes, &CIFCurStyle->cs_hierLayers, - FALSE, TRUE); + CIFGen(CIFTotalDef, use->cu_def, &B, CIFTotalPlanes, + &CIFCurStyle->cs_hierLayers, FALSE, TRUE); /* D */ @@ -967,8 +967,8 @@ cifHierArrayFunc(scx, output) (void) DBArraySr(use, &expandedArea, cifHierElementFunc, (ClientData) &D); CIFErrorDef = use->cu_parent; - CIFGen(CIFTotalDef, &D, CIFTotalPlanes, &CIFCurStyle->cs_hierLayers, - FALSE, TRUE); + CIFGen(CIFTotalDef, use->cu_def, &D, CIFTotalPlanes, + &CIFCurStyle->cs_hierLayers, FALSE, TRUE); } if (anyInteractions) diff --git a/cif/CIFint.h b/cif/CIFint.h index c3d630fe..c1a14dcb 100644 --- a/cif/CIFint.h +++ b/cif/CIFint.h @@ -45,6 +45,7 @@ typedef struct bloat_data { + bool bl_isCif; /* TRUE if types of bl_distance are CIF types */ int bl_plane; /* Plane on which a bloat or squares * operation is valid. */ diff --git a/cif/CIFmain.c b/cif/CIFmain.c index d81a794a..959b70c2 100644 --- a/cif/CIFmain.c +++ b/cif/CIFmain.c @@ -327,7 +327,23 @@ CIFNameToMask(name, result, depend) { cl = CIFCurStyle->cs_layers[j]; for (op = cl->cl_ops; op != NULL; op = op->co_next) + { TTMaskSetMask(depend, &op->co_cifMask); + + /* Bloat layers may depend on CIF layers */ + /* Currently supported only with bloat-all */ + + if (op->co_opcode == CIFOP_BLOATALL) + { + BloatData *bloats = (BloatData *)op->co_client; + TileType ttype; + + if (bloats->bl_isCif == TRUE) + for (ttype = 0; ttype < TT_MAXTYPES; ttype++) + if (bloats->bl_distance[ttype] > 0) + TTMaskSetType(depend, ttype); + } + } } } return TRUE; diff --git a/cif/CIFrdcl.c b/cif/CIFrdcl.c index 4cd26365..02114afb 100644 --- a/cif/CIFrdcl.c +++ b/cif/CIFrdcl.c @@ -572,7 +572,7 @@ CIFPaintCurrent(filetype) CIFOp *op; plane = CIFGenLayer(cifCurReadStyle->crs_layers[i]->crl_ops, - &TiPlaneRect, (CellDef *) NULL, cifCurReadPlanes); + &TiPlaneRect, (CellDef *)NULL, (CellDef *)NULL, cifCurReadPlanes); /* 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 64b4762e..4b880266 100644 --- a/cif/CIFsee.c +++ b/cif/CIFsee.c @@ -163,7 +163,8 @@ CIFPaintLayer(rootDef, area, cifLayer, magicLayer, paintDef) (void) DBTreeSrTiles(&scx, &DBAllButSpaceAndDRCBits, 0, cifHierCopyFunc, (ClientData) CIFComponentDef); oldCount = DBWFeedbackCount; - CIFGen(CIFComponentDef, area, CIFPlanes, &depend, TRUE, TRUE); + + CIFGen(CIFComponentDef, rootDef, area, CIFPlanes, &depend, TRUE, TRUE); DBCellClearDef(CIFComponentDef); /* Report any errors that occurred. */ @@ -277,7 +278,7 @@ CIFSeeLayer(rootDef, area, layer) (void) DBTreeSrTiles(&scx, &DBAllButSpaceAndDRCBits, 0, cifHierCopyFunc, (ClientData) CIFComponentDef); oldCount = DBWFeedbackCount; - CIFGen(CIFComponentDef, area, CIFPlanes, &depend, TRUE, TRUE); + CIFGen(CIFComponentDef, rootDef, area, CIFPlanes, &depend, TRUE, TRUE); DBCellClearDef(CIFComponentDef); /* Report any errors that occurred. */ @@ -440,7 +441,7 @@ CIFCoverageLayer(rootDef, area, layer) scx.scx_trans = GeoIdentityTransform; (void) DBTreeSrTiles(&scx, &DBAllButSpaceAndDRCBits, 0, cifHierCopyFunc, (ClientData) CIFComponentDef); - CIFGen(CIFComponentDef, area, CIFPlanes, &depend, TRUE, TRUE); + CIFGen(CIFComponentDef, rootDef, area, CIFPlanes, &depend, TRUE, TRUE); DBCellClearDef(CIFComponentDef); cstats.coverage = 0; diff --git a/cif/CIFtech.c b/cif/CIFtech.c index a2d46b3b..081f5b0d 100644 --- a/cif/CIFtech.c +++ b/cif/CIFtech.c @@ -210,7 +210,7 @@ cifTechStyleInit() */ void -cifParseLayers(string, style, paintMask, cifMask,spaceOK) +cifParseLayers(string, style, paintMask, cifMask, spaceOK) char *string; /* List of layers. */ CIFStyle *style; /* Gives CIF style for parsing string.*/ TileTypeBitMask *paintMask; /* Place to store mask of paint layers. If @@ -524,7 +524,7 @@ CIFTechLine(sectionName, argc, argv) int argc; /* Number of fields on line. */ char *argv[]; /* Values of fields. */ { - TileTypeBitMask mask, tempMask, bloatLayers; + TileTypeBitMask mask, tempMask, cifMask, bloatLayers; int i, j, l, distance; CIFLayer *newLayer; CIFOp *newOp = NULL; @@ -851,7 +851,7 @@ CIFTechLine(sectionName, argc, argv) cifCurOp = (CIFOp *) mallocMagic(sizeof(CIFOp)); cifCurOp->co_opcode = CIFOP_OR; cifParseLayers(argv[2], CIFCurStyle, &cifCurOp->co_paintMask, - &cifCurOp->co_cifMask,FALSE); + &cifCurOp->co_cifMask, FALSE); cifCurOp->co_distance = 0; cifCurOp->co_next = NULL; cifCurOp->co_client = (ClientData)NULL; @@ -1093,32 +1093,49 @@ CIFTechLine(sectionName, argc, argv) for (i = 0; i < TT_MAXTYPES; i++) bloats->bl_distance[i] = 0; newOp->co_client = (ClientData)bloats; - cifParseLayers(argv[2], CIFCurStyle, &mask, &tempMask, TRUE); + cifParseLayers(argv[2], CIFCurStyle, &mask, &cifMask, TRUE); + + /* 5/25/2020: Lifting restriction that bloatLayers types */ + /* cannot be CIF or temp layers. However, CIF/temp layers */ + /* and magic database layers may not be mixed. */ + + if (!TTMaskIsZero(&mask) && !TTMaskIsZero(&cifMask)) + TechError("Can't mix CIF and magic layers in bloat statement.\n"); /* 10/15/2019: Lifting restriction that the types that */ /* trigger the bloating must be in the same plane as the */ /* types that are bloated into. */ TTMaskZero(&bloatLayers); - TTMaskSetMask(&bloatLayers, &mask); - if (!TTMaskEqual(&tempMask, &DBZeroTypeBits)) - TechError("Can't use templayers in bloat statement.\n"); - - for (i = 0; i < TT_MAXTYPES; i++) - if (TTMaskHasType(&mask, i)) - bloats->bl_distance[i] = 1; - goto bloatCheck; + if (!TTMaskIsZero(&mask)) + { + bloats->bl_isCif = FALSE; + TTMaskSetMask(&bloatLayers, &mask); + for (i = 0; i < TT_MAXTYPES; i++) + if (TTMaskHasType(&mask, i)) + bloats->bl_distance[i] = 1; + } + else + { + bloats->bl_isCif = TRUE; + TTMaskSetMask(&bloatLayers, &cifMask); + for (i = 0; i < TT_MAXTYPES; i++) + if (TTMaskHasType(&cifMask, i)) + bloats->bl_distance[i] = 1; + } + break; case CIFOP_BLOAT: case CIFOP_BLOATMIN: case CIFOP_BLOATMAX: if (argc < 4) goto wrongNumArgs; cifParseLayers(argv[1], CIFCurStyle, &newOp->co_paintMask, - (TileTypeBitMask *) NULL,FALSE); + (TileTypeBitMask *)NULL, FALSE); argc -= 2; bloatArg = argv + 2; bloatLayers = newOp->co_paintMask; bloats = (BloatData *)mallocMagic(sizeof(BloatData)); + bloats->bl_isCif = FALSE; for (i = 0; i < TT_MAXTYPES; i++) bloats->bl_distance[i] = 0; newOp->co_client = (ClientData)bloats; @@ -1133,7 +1150,7 @@ CIFTechLine(sectionName, argc, argv) } else { - cifParseLayers(*bloatArg, CIFCurStyle, &mask, &tempMask,TRUE); + cifParseLayers(*bloatArg, CIFCurStyle, &mask, &tempMask, TRUE); TTMaskSetMask(&bloatLayers, &mask); } if (!TTMaskEqual(&tempMask, &DBZeroTypeBits)) @@ -1859,7 +1876,12 @@ CIFTechFinal() for (j = 0; j < TT_MAXTYPES; j++) { if (bloats->bl_distance[j] != bloats->bl_distance[TT_SPACE]) - TTMaskSetType(&ourYank, j); + { + if (bloats->bl_isCif) + TTMaskSetType(&ourDepend, j); + else + TTMaskSetType(&ourYank, j); + } } needThisLayer = TRUE; break; diff --git a/cif/CIFwrite.c b/cif/CIFwrite.c index d1759bf7..558f147c 100644 --- a/cif/CIFwrite.c +++ b/cif/CIFwrite.c @@ -378,7 +378,7 @@ cifOutFunc(def, f) GEO_EXPAND(&def->cd_bbox, CIFCurStyle->cs_radius, &bigArea); CIFErrorDef = def; - CIFGen(def, &bigArea, CIFPlanes, &DBAllTypeBits, TRUE, TRUE); + CIFGen(def, def, &bigArea, CIFPlanes, &DBAllTypeBits, TRUE, TRUE); if (!CIFHierWriteDisable) CIFGenSubcells(def, &bigArea, CIFPlanes); if (!CIFArrayWriteDisable) diff --git a/drc/DRCcif.c b/drc/DRCcif.c index 80134220..cd7659ae 100644 --- a/drc/DRCcif.c +++ b/drc/DRCcif.c @@ -540,7 +540,8 @@ drcCifCheck(arg) arg->dCD_rect = &cifrect; oldTiles = DRCstatTiles; - CIFGen(arg->dCD_celldef, checkRect, CIFPlanes, &DBAllTypeBits, TRUE, TRUE); + CIFGen(arg->dCD_celldef, arg->dCD_celldef, checkRect, CIFPlanes, + &DBAllTypeBits, TRUE, TRUE); for (i = 0; i < drcCifStyle->cs_nLayers; i++) { diff --git a/graphics/W3Dmain.c b/graphics/W3Dmain.c index 7d1944f3..656f37b8 100644 --- a/graphics/W3Dmain.c +++ b/graphics/W3Dmain.c @@ -1739,7 +1739,7 @@ W3DCIFredisplay(w, rootArea, clipArea) scx.scx_trans = GeoIdentityTransform; (void) DBTreeSrTiles(&scx, &DBAllButSpaceAndDRCBits, 0, cifHierCopyFunc, (ClientData) CIFComponentDef); - CIFGen(CIFComponentDef, &clipRect, CIFPlanes, &DBAllTypeBits, TRUE, TRUE); + CIFGen(CIFComponentDef, cellDef, &clipRect, CIFPlanes, &DBAllTypeBits, TRUE, TRUE); DBCellClearDef(CIFComponentDef); w3dClear();