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 */
|
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;
|
atotal = 0;
|
||||||
|
|
||||||
/* Search all sides for connected space tiles, and accumulate the total */
|
/* Search all sides for connected space tiles, and accumulate the */
|
||||||
/* area. If any connected tile borders infinity, then stop searching */
|
/* total area. If any connected tile borders infinity, then stop */
|
||||||
/* because the area is not enclosed. */
|
/* searching because the area is not enclosed. */
|
||||||
|
|
||||||
cifGatherFunc(tile, &atotal, CLOSE_SEARCH);
|
cifGatherFunc(tile, &atotal, CLOSE_SEARCH);
|
||||||
|
|
||||||
/* If the total area is smaller than the rule area, then paint all the */
|
/* If the total area is smaller than the rule area, then paint all */
|
||||||
/* tile areas into the destination plane. */
|
/* 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);
|
cifGatherFunc(tile, &atotal, CLOSE_FILL);
|
||||||
}
|
}
|
||||||
|
|
@ -2134,7 +2183,6 @@ cifCloseFunc(
|
||||||
{
|
{
|
||||||
cifGatherFunc(tile, &atotal, CLOSE_DONE);
|
cifGatherFunc(tile, &atotal, CLOSE_DONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -5264,6 +5312,22 @@ CIFGenLayer(
|
||||||
}
|
}
|
||||||
break;
|
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:
|
case CIFOP_MAXRECT:
|
||||||
cifPlane = curPlane;
|
cifPlane = curPlane;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -141,6 +141,7 @@ typedef struct cifop
|
||||||
* which will be painted into parent cells instead of the
|
* which will be painted into parent cells instead of the
|
||||||
* current cell. This replaces the "fault" method.
|
* current cell. This replaces the "fault" method.
|
||||||
* CIFOP_CLOSE - Added 11/25/19---close up areas smaller than indicated
|
* 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_BRIDGE - Added 6/11/20---Bridge across catecorner gaps
|
||||||
* CIFOP_BRIDGELIM - Added 27/07/20---Bridge across catecorner gaps, but with limiting layers
|
* 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.
|
* 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_INTERACT 19
|
||||||
#define CIFOP_COPYUP 20
|
#define CIFOP_COPYUP 20
|
||||||
#define CIFOP_CLOSE 21
|
#define CIFOP_CLOSE 21
|
||||||
#define CIFOP_BRIDGE 22
|
#define CIFOP_MANHATTAN 22
|
||||||
#define CIFOP_BRIDGELIM 23
|
#define CIFOP_BRIDGE 23
|
||||||
#define CIFOP_MASKHINTS 24
|
#define CIFOP_BRIDGELIM 24
|
||||||
|
#define CIFOP_MASKHINTS 25
|
||||||
|
|
||||||
/* Definitions of bit fields used in the value of co_client for CIFOP_INTERACT */
|
/* Definitions of bit fields used in the value of co_client for CIFOP_INTERACT */
|
||||||
#define CIFOP_INT_NOT 0x1 /* Inverted sense (not interacting) */
|
#define CIFOP_INT_NOT 0x1 /* Inverted sense (not interacting) */
|
||||||
|
|
|
||||||
|
|
@ -111,6 +111,7 @@ cifTechFreeStyle(void)
|
||||||
case CIFOP_MAXRECT:
|
case CIFOP_MAXRECT:
|
||||||
case CIFOP_BOUNDARY:
|
case CIFOP_BOUNDARY:
|
||||||
case CIFOP_INTERACT:
|
case CIFOP_INTERACT:
|
||||||
|
case CIFOP_MANHATTAN:
|
||||||
/* These options use co_client to hold a single */
|
/* These options use co_client to hold a single */
|
||||||
/* integer value, so it is not allocated. */
|
/* integer value, so it is not allocated. */
|
||||||
break;
|
break;
|
||||||
|
|
@ -1091,6 +1092,8 @@ CIFTechLine(
|
||||||
newOp->co_opcode = CIFOP_MASKHINTS;
|
newOp->co_opcode = CIFOP_MASKHINTS;
|
||||||
else if (strcmp(argv[0], "close") == 0)
|
else if (strcmp(argv[0], "close") == 0)
|
||||||
newOp->co_opcode = CIFOP_CLOSE;
|
newOp->co_opcode = CIFOP_CLOSE;
|
||||||
|
else if (strcmp(argv[0], "orthogonal") == 0)
|
||||||
|
newOp->co_opcode = CIFOP_MANHATTAN;
|
||||||
else if (strcmp(argv[0], "bridge") == 0)
|
else if (strcmp(argv[0], "bridge") == 0)
|
||||||
newOp->co_opcode = CIFOP_BRIDGE;
|
newOp->co_opcode = CIFOP_BRIDGE;
|
||||||
else if (strcmp(argv[0], "bridge-lim") == 0)
|
else if (strcmp(argv[0], "bridge-lim") == 0)
|
||||||
|
|
@ -1133,7 +1136,6 @@ CIFTechLine(
|
||||||
case CIFOP_GROWMIN:
|
case CIFOP_GROWMIN:
|
||||||
case CIFOP_GROW_G:
|
case CIFOP_GROW_G:
|
||||||
case CIFOP_SHRINK:
|
case CIFOP_SHRINK:
|
||||||
case CIFOP_CLOSE:
|
|
||||||
if (argc != 2) goto wrongNumArgs;
|
if (argc != 2) goto wrongNumArgs;
|
||||||
newOp->co_distance = atoi(argv[1]);
|
newOp->co_distance = atoi(argv[1]);
|
||||||
if (newOp->co_distance <= 0)
|
if (newOp->co_distance <= 0)
|
||||||
|
|
@ -1143,6 +1145,26 @@ CIFTechLine(
|
||||||
}
|
}
|
||||||
break;
|
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:
|
case CIFOP_BRIDGE:
|
||||||
if (argc != 3) goto wrongNumArgs;
|
if (argc != 3) goto wrongNumArgs;
|
||||||
newOp->co_distance = atoi(argv[1]);
|
newOp->co_distance = atoi(argv[1]);
|
||||||
|
|
@ -1334,6 +1356,19 @@ bloatCheck:
|
||||||
goto wrongNumArgs;
|
goto wrongNumArgs;
|
||||||
break;
|
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:
|
case CIFOP_BBOX:
|
||||||
if (argc == 2)
|
if (argc == 2)
|
||||||
{
|
{
|
||||||
|
|
@ -1925,7 +1960,7 @@ CIFTechFinal(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Presence of op->co_opcode in CIFOP_OR indicates a copy */
|
/* 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 */
|
/* CIFOP_BBOX and CIFOP_MAXRECT uses the co_client field */
|
||||||
/* as a flag field, while CIFOP_NET and CIFOP_MASKHINTS */
|
/* as a flag field, while CIFOP_NET and CIFOP_MASKHINTS */
|
||||||
/* uses it for a string. */
|
/* uses it for a string. */
|
||||||
|
|
@ -1938,6 +1973,7 @@ CIFTechFinal(void)
|
||||||
case CIFOP_MASKHINTS:
|
case CIFOP_MASKHINTS:
|
||||||
case CIFOP_BOUNDARY:
|
case CIFOP_BOUNDARY:
|
||||||
case CIFOP_MAXRECT:
|
case CIFOP_MAXRECT:
|
||||||
|
case CIFOP_MANHATTAN:
|
||||||
case CIFOP_NET:
|
case CIFOP_NET:
|
||||||
break;
|
break;
|
||||||
case CIFOP_BRIDGELIM:
|
case CIFOP_BRIDGELIM:
|
||||||
|
|
@ -2472,6 +2508,7 @@ CIFTechOutputScale(
|
||||||
case CIFOP_BOUNDARY:
|
case CIFOP_BOUNDARY:
|
||||||
case CIFOP_MASKHINTS:
|
case CIFOP_MASKHINTS:
|
||||||
case CIFOP_MAXRECT:
|
case CIFOP_MAXRECT:
|
||||||
|
case CIFOP_MANHATTAN:
|
||||||
case CIFOP_NET:
|
case CIFOP_NET:
|
||||||
case CIFOP_INTERACT:
|
case CIFOP_INTERACT:
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue