Added a new "orthogonal" operator to cifoutput to allow non-
manhattan shapes (especially minimum-sized ones) to be eliminated, as these can survive a shrink-grow operation intended to get rid of such shapes. This implementation may not be in its final form but should suffice for now.
This commit is contained in:
parent
dde7144966
commit
6b9efefc02
78
cif/CIFgen.c
78
cif/CIFgen.c
|
|
@ -2082,6 +2082,53 @@ cifBridgeCheckFunc(
|
|||
return 0; /* Nothing found here, so keep going */
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* cifOrthogonalFunc --
|
||||
*
|
||||
* Called for each relevant tile during "orthogonal" operations.
|
||||
*
|
||||
* Results:
|
||||
* Always returns 0 to keep the search alive.
|
||||
*
|
||||
* Side effects:
|
||||
* Paints into cifNewPlane. Tiles in old plane are copied as-is
|
||||
* if they are not split tiles. Split tiles are either replaced
|
||||
* with a rectangle of type "1" or "0" depending on whether the
|
||||
* option is "fill" or "remove", respectively.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
cifOrthogonalFunc(
|
||||
Tile *tile,
|
||||
const PaintResultType *table) /* Table to be used for painting. */
|
||||
{
|
||||
Rect area;
|
||||
TileType oldType = TiGetTypeExact(tile);
|
||||
|
||||
TiToRect(tile, &area);
|
||||
|
||||
/* In scaling the tile, watch out for infinities!! If something
|
||||
* is already infinity, don't change it. */
|
||||
|
||||
if (area.r_xbot > TiPlaneRect.r_xbot) area.r_xbot *= cifScale;
|
||||
if (area.r_ybot > TiPlaneRect.r_ybot) area.r_ybot *= cifScale;
|
||||
if (area.r_xtop < TiPlaneRect.r_xtop) area.r_xtop *= cifScale;
|
||||
if (area.r_ytop < TiPlaneRect.r_ytop) area.r_ytop *= cifScale;
|
||||
|
||||
/* Diagonal tiles get replaced with non-diagonal tiles */
|
||||
|
||||
if (oldType & TT_DIAGONAL)
|
||||
DBPaintPlane(cifPlane, &area, table, (PaintUndoInfo *) NULL);
|
||||
else
|
||||
DBPaintPlane(cifPlane, &area, CIFPaintTable, (PaintUndoInfo *) NULL);
|
||||
|
||||
CIFTileOps += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
|
|
@ -2117,16 +2164,18 @@ cifCloseFunc(
|
|||
|
||||
atotal = 0;
|
||||
|
||||
/* Search all sides for connected space tiles, and accumulate the total */
|
||||
/* area. If any connected tile borders infinity, then stop searching */
|
||||
/* because the area is not enclosed. */
|
||||
/* Search all sides for connected space tiles, and accumulate the */
|
||||
/* total area. If any connected tile borders infinity, then stop */
|
||||
/* searching because the area is not enclosed. */
|
||||
|
||||
cifGatherFunc(tile, &atotal, CLOSE_SEARCH);
|
||||
|
||||
/* If the total area is smaller than the rule area, then paint all the */
|
||||
/* tile areas into the destination plane. */
|
||||
/* If the total area is smaller than the rule area, then paint all */
|
||||
/* the tile areas into the destination plane. A rule area of zero */
|
||||
/* indicates that any enclosed area, no matter how large, should be */
|
||||
/* filled. */
|
||||
|
||||
if ((atotal != INFINITY) && (atotal < growDistance))
|
||||
if ((atotal != INFINITY) && ((atotal < growDistance) || (growDistance == 0)))
|
||||
{
|
||||
cifGatherFunc(tile, &atotal, CLOSE_FILL);
|
||||
}
|
||||
|
|
@ -2134,7 +2183,6 @@ cifCloseFunc(
|
|||
{
|
||||
cifGatherFunc(tile, &atotal, CLOSE_DONE);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -5264,6 +5312,22 @@ CIFGenLayer(
|
|||
}
|
||||
break;
|
||||
|
||||
case CIFOP_MANHATTAN:
|
||||
DBClearPaintPlane(nextPlane);
|
||||
cifPlane = nextPlane;
|
||||
cifScale = 1;
|
||||
DBSrPaintArea((Tile *) NULL, curPlane, &TiPlaneRect,
|
||||
&CIFSolidBits, cifOrthogonalFunc,
|
||||
(op->co_client == (ClientData)1) ?
|
||||
(ClientData) CIFPaintTable :
|
||||
(ClientData) CIFEraseTable);
|
||||
|
||||
temp = curPlane;
|
||||
curPlane = nextPlane;
|
||||
nextPlane = temp;
|
||||
break;
|
||||
|
||||
|
||||
case CIFOP_MAXRECT:
|
||||
cifPlane = curPlane;
|
||||
|
||||
|
|
|
|||
|
|
@ -141,6 +141,7 @@ typedef struct cifop
|
|||
* which will be painted into parent cells instead of the
|
||||
* current cell. This replaces the "fault" method.
|
||||
* CIFOP_CLOSE - Added 11/25/19---close up areas smaller than indicated
|
||||
* CIFOP_MANHATTAN - Added 3/27/25---remove or fill nonmanhattan areas
|
||||
* CIFOP_BRIDGE - Added 6/11/20---Bridge across catecorner gaps
|
||||
* CIFOP_BRIDGELIM - Added 27/07/20---Bridge across catecorner gaps, but with limiting layers
|
||||
* CIFOP_MASKHINTS - Added 12/14/20---Add geometry from cell properties, if any.
|
||||
|
|
@ -167,9 +168,10 @@ typedef struct cifop
|
|||
#define CIFOP_INTERACT 19
|
||||
#define CIFOP_COPYUP 20
|
||||
#define CIFOP_CLOSE 21
|
||||
#define CIFOP_BRIDGE 22
|
||||
#define CIFOP_BRIDGELIM 23
|
||||
#define CIFOP_MASKHINTS 24
|
||||
#define CIFOP_MANHATTAN 22
|
||||
#define CIFOP_BRIDGE 23
|
||||
#define CIFOP_BRIDGELIM 24
|
||||
#define CIFOP_MASKHINTS 25
|
||||
|
||||
/* Definitions of bit fields used in the value of co_client for CIFOP_INTERACT */
|
||||
#define CIFOP_INT_NOT 0x1 /* Inverted sense (not interacting) */
|
||||
|
|
|
|||
|
|
@ -111,6 +111,7 @@ cifTechFreeStyle(void)
|
|||
case CIFOP_MAXRECT:
|
||||
case CIFOP_BOUNDARY:
|
||||
case CIFOP_INTERACT:
|
||||
case CIFOP_MANHATTAN:
|
||||
/* These options use co_client to hold a single */
|
||||
/* integer value, so it is not allocated. */
|
||||
break;
|
||||
|
|
@ -1091,6 +1092,8 @@ CIFTechLine(
|
|||
newOp->co_opcode = CIFOP_MASKHINTS;
|
||||
else if (strcmp(argv[0], "close") == 0)
|
||||
newOp->co_opcode = CIFOP_CLOSE;
|
||||
else if (strcmp(argv[0], "orthogonal") == 0)
|
||||
newOp->co_opcode = CIFOP_MANHATTAN;
|
||||
else if (strcmp(argv[0], "bridge") == 0)
|
||||
newOp->co_opcode = CIFOP_BRIDGE;
|
||||
else if (strcmp(argv[0], "bridge-lim") == 0)
|
||||
|
|
@ -1133,7 +1136,6 @@ CIFTechLine(
|
|||
case CIFOP_GROWMIN:
|
||||
case CIFOP_GROW_G:
|
||||
case CIFOP_SHRINK:
|
||||
case CIFOP_CLOSE:
|
||||
if (argc != 2) goto wrongNumArgs;
|
||||
newOp->co_distance = atoi(argv[1]);
|
||||
if (newOp->co_distance <= 0)
|
||||
|
|
@ -1143,6 +1145,26 @@ CIFTechLine(
|
|||
}
|
||||
break;
|
||||
|
||||
case CIFOP_CLOSE:
|
||||
/* "close" is like "grow" and "shrink" except that it can have
|
||||
* no argument, in which case any closed shape of any size
|
||||
* will be closed (useful for finding enclosed areas).
|
||||
*/
|
||||
if (argc == 1)
|
||||
newOp->co_distance = 0;
|
||||
else if (argc != 2)
|
||||
goto wrongNumArgs;
|
||||
else
|
||||
{
|
||||
newOp->co_distance = atoi(argv[1]);
|
||||
if (newOp->co_distance <= 0)
|
||||
{
|
||||
TechError("Grow/shrink distance must be greater than zero.\n");
|
||||
goto errorReturn;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CIFOP_BRIDGE:
|
||||
if (argc != 3) goto wrongNumArgs;
|
||||
newOp->co_distance = atoi(argv[1]);
|
||||
|
|
@ -1334,6 +1356,19 @@ bloatCheck:
|
|||
goto wrongNumArgs;
|
||||
break;
|
||||
|
||||
case CIFOP_MANHATTAN:
|
||||
if (argc == 2)
|
||||
{
|
||||
if (!strcmp(argv[1], "fill"))
|
||||
newOp->co_client = (ClientData)1;
|
||||
else if (strcmp(argv[1], "remove"))
|
||||
TechError("Orthogonal takes only one optional argument "
|
||||
"\"fill\" or \"remove\" (default).\n");
|
||||
}
|
||||
else if (argc != 1)
|
||||
goto wrongNumArgs;
|
||||
break;
|
||||
|
||||
case CIFOP_BBOX:
|
||||
if (argc == 2)
|
||||
{
|
||||
|
|
@ -1925,7 +1960,7 @@ CIFTechFinal(void)
|
|||
}
|
||||
}
|
||||
/* Presence of op->co_opcode in CIFOP_OR indicates a copy */
|
||||
/* of the SquaresData pointer from a following operator */
|
||||
/* of the SquaresData pointer from a following operator. */
|
||||
/* CIFOP_BBOX and CIFOP_MAXRECT uses the co_client field */
|
||||
/* as a flag field, while CIFOP_NET and CIFOP_MASKHINTS */
|
||||
/* uses it for a string. */
|
||||
|
|
@ -1938,6 +1973,7 @@ CIFTechFinal(void)
|
|||
case CIFOP_MASKHINTS:
|
||||
case CIFOP_BOUNDARY:
|
||||
case CIFOP_MAXRECT:
|
||||
case CIFOP_MANHATTAN:
|
||||
case CIFOP_NET:
|
||||
break;
|
||||
case CIFOP_BRIDGELIM:
|
||||
|
|
@ -2472,6 +2508,7 @@ CIFTechOutputScale(
|
|||
case CIFOP_BOUNDARY:
|
||||
case CIFOP_MASKHINTS:
|
||||
case CIFOP_MAXRECT:
|
||||
case CIFOP_MANHATTAN:
|
||||
case CIFOP_NET:
|
||||
case CIFOP_INTERACT:
|
||||
break;
|
||||
|
|
|
|||
Loading…
Reference in New Issue