Added a new option "-doinplace" for the "flatten" command. This

should have been done a long time ago!  Allows an instance to be
flattened in place inside a cell def, which otherwise requires
a complicated set of commands to do.  Also:  Modified the polygon
handling routine from the previous commit so that it correctly
removes the polygon cell defs after flattening them into the
parent cell.
This commit is contained in:
Tim Edwards 2022-12-14 12:44:30 -05:00
parent 13a1bfcc2e
commit e5813f51fa
4 changed files with 74 additions and 8 deletions

View File

@ -1 +1 @@
8.3.352
8.3.353

View File

@ -287,6 +287,13 @@ calmaExact()
* in fact can be much faster than reading the polygons
* directly into the cell from GDS.
*
* Return value:
* Return 0 to keep the search going
*
* Side effects:
* Polygons are copied from use->cu_def to parent.
* use->cu_def is deleted.
*
* ----------------------------------------------------------------------------
*/
@ -298,6 +305,7 @@ calmaFlattenPolygonFunc(use, parent)
int i;
CellUse dummy;
SearchContext scx;
HashEntry *he;
if (use->cu_def == NULL || use->cu_def->cd_name == NULL) return 0;
if (strncmp(use->cu_def->cd_name, "polygon", 7)) return 0;
@ -310,12 +318,14 @@ calmaFlattenPolygonFunc(use, parent)
scx.scx_trans = GeoIdentityTransform;
DBCellCopyAllPaint(&scx, &DBAllButSpaceAndDRCBits, 0, &dummy);
DBDeleteCellNoModify(use);
HashRemove(&CifCellTable, use->cu_def->cd_name);
/* There should only be one use, so it can just be cleared */
use->cu_def->cd_parents = (CellUse *)NULL;
DBCellDeleteDef(use->cu_def);
return 0; /* Keep the search going */
}
/*
* ----------------------------------------------------------------------------
*
@ -347,6 +357,7 @@ calmaParseStructure(filename)
int timestampval = 0;
int suffix;
int mfactor;
int locPolygonCount;
OFFTYPE filepos;
bool was_called;
bool was_initialized;
@ -354,6 +365,8 @@ calmaParseStructure(filename)
bool do_flatten;
CellDef *def;
locPolygonCount = CalmaPolygonCount;
/* Make sure this is a structure; if not, let the caller know we're done */
PEEKRH(nbytes, rtype);
if (nbytes <= 0 || rtype != CALMA_BGNSTR)
@ -587,11 +600,8 @@ calmaParseStructure(filename)
CIFPaintCurrent(FILE_CALMA);
}
if ((!CalmaSubcellPolygons) && (CalmaPolygonCount > 0))
{
if ((!CalmaSubcellPolygons) && (locPolygonCount < CalmaPolygonCount))
DBCellEnum(cifReadCellDef, calmaFlattenPolygonFunc, (ClientData)cifReadCellDef);
CalmaPolygonCount = 0;
}
DBAdjustLabelsNew(cifReadCellDef, &TiPlaneRect,
(cifCurReadStyle->crs_flags & CRF_NO_RECONNECT_LABELS) ? 1 : 0);

View File

@ -1959,7 +1959,7 @@ CmdFlatten(w, cmd)
TxCommand *cmd;
{
int rval, xMask;
bool dolabels, dobox, toplabels, invert, doports;
bool dolabels, dobox, toplabels, invert, doports, doinplace;
char *destname;
CellDef *newdef;
CellUse *newuse;
@ -1972,6 +1972,7 @@ CmdFlatten(w, cmd)
toplabels = FALSE;
dobox = FALSE;
doports = TRUE;
doinplace = FALSE;
rval = 0;
if (cmd->tx_argc > 2)
@ -2000,6 +2001,9 @@ CmdFlatten(w, cmd)
case 'b':
dobox = (invert) ? FALSE : TRUE;
break;
case 'i':
doinplace = (invert) ? FALSE : TRUE;
break;
case 'l':
dolabels = (invert) ? FALSE : TRUE;
break;
@ -2020,7 +2024,8 @@ CmdFlatten(w, cmd)
break;
default:
TxError("options are: -nolabels, -nosubcircuits, -noports, "
"-novendor, -dotoplabels, -doproperty, -dobox\n");
"-novendor, -dotoplabels, -doproperty, -dobox, "
"-doinplace\n");
break;
}
}
@ -2034,6 +2039,51 @@ CmdFlatten(w, cmd)
TxError("usage: flatten [-<option>...] destcell\n");
return;
}
/* Flatten-in-place: destname is an instance, not a cell def */
if (doinplace)
{
HashEntry *he;
if (EditCellUse == NULL)
{
TxError("The cell def is not editable.\n");
return;
}
he = HashLookOnly(&EditCellUse->cu_def->cd_idHash, destname);
if (he == NULL)
{
TxError("No cell use %s found in edit cell.\n", destname);
return;
}
scx.scx_use = (CellUse *)HashGetValue(he);
scx.scx_trans = GeoIdentityTransform;
scx.scx_area = scx.scx_use->cu_def->cd_bbox;
UndoDisable();
DBCellCopyAllPaint(&scx, &DBAllButSpaceAndDRCBits, xMask, EditCellUse);
if (dolabels)
FlatCopyAllLabels(&scx, &DBAllTypeBits, xMask, EditCellUse);
else if (toplabels)
{
int savemask = scx.scx_use->cu_expandMask;
scx.scx_use->cu_expandMask = CU_DESCEND_SPECIAL;
DBCellCopyAllLabels(&scx, &DBAllTypeBits, CU_DESCEND_SPECIAL, EditCellUse);
scx.scx_use->cu_expandMask = savemask;
}
if (xMask != CU_DESCEND_ALL)
DBCellCopyAllCells(&scx, xMask, EditCellUse, (Rect *)NULL);
/* Remove the use */
DBDeleteCell(scx.scx_use);
UndoEnable();
return;
}
/* create the new def */
newdef = DBCellLookDef(destname);
if ((newdef != NULL) && (dobox == FALSE))

View File

@ -71,6 +71,12 @@ Flatten edit cell into the indicated destination cell.
<DT> <B>-dobox</B>
<DD> When this option is specified, magic flattens only the area
of the circuit that is inside the boundary of the cursor box.
<DT> <B>-doinplace</B>
<DD> When this option is specified, <I>cellname</I> must be the
name of a cell <I>use</I> (instance), not a cell <I>definition</I>.
The cell use <I>cellname</I> is assumed to exist in the current
edit cell. The cell use will be removed from the edit cell and
replaced with its flattened contents.
</DL>
Note that <I>cellname</I> is a top-level cell but is not displayed