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.
This commit is contained in:
Tim Edwards 2020-05-26 14:29:36 -04:00
parent a908893ae3
commit 3203eec28c
12 changed files with 131 additions and 50 deletions

View File

@ -1 +1 @@
8.3.15
8.3.16

View File

@ -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)

View File

@ -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,

View File

@ -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)

View File

@ -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.
*/

View File

@ -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;

View File

@ -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.

View File

@ -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;

View File

@ -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;

View File

@ -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)

View File

@ -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++)
{

View File

@ -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();