Added a new selection command option "select intersect" that selects
the area of intersection between any number of types.
This commit is contained in:
parent
e152deb97b
commit
7cb88ffceb
147
commands/CmdRS.c
147
commands/CmdRS.c
|
|
@ -528,6 +528,26 @@ CmdSee(w, cmd)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define SEL_AREA 0
|
||||||
|
#define SEL_VISIBLE 1
|
||||||
|
#define SEL_CELL 2
|
||||||
|
#define SEL_LABELS 3
|
||||||
|
#define SEL_INTERSECT 4
|
||||||
|
#define SEL_CLEAR 5
|
||||||
|
#define SEL_FLAT 6
|
||||||
|
#define SEL_HELP 7
|
||||||
|
#define SEL_KEEP 8
|
||||||
|
#define SEL_MOVE 9
|
||||||
|
#define SEL_PICK 10
|
||||||
|
#define SEL_SAVE 11
|
||||||
|
#define SEL_FEEDBACK 12
|
||||||
|
#define SEL_BBOX 13
|
||||||
|
#define SEL_BOX 14
|
||||||
|
#define SEL_CHUNK 15
|
||||||
|
#define SEL_REGION 16
|
||||||
|
#define SEL_NET 17
|
||||||
|
#define SEL_SHORT 18
|
||||||
|
#define SEL_DEFAULT 19
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ----------------------------------------------------------------------------
|
* ----------------------------------------------------------------------------
|
||||||
|
|
@ -550,86 +570,10 @@ CmdSee(w, cmd)
|
||||||
|
|
||||||
/* ARGSUSED */
|
/* ARGSUSED */
|
||||||
void
|
void
|
||||||
cmdSelectArea(layers, less)
|
cmdSelectArea(layers, less, option)
|
||||||
char *layers; /* Which layers are to be selected. */
|
|
||||||
bool less;
|
|
||||||
{
|
|
||||||
SearchContext scx;
|
|
||||||
TileTypeBitMask mask;
|
|
||||||
int windowMask, xMask;
|
|
||||||
DBWclientRec *crec;
|
|
||||||
MagWindow *window;
|
|
||||||
|
|
||||||
bzero(&scx, sizeof(SearchContext));
|
|
||||||
window = ToolGetBoxWindow(&scx.scx_area, &windowMask);
|
|
||||||
if (window == NULL)
|
|
||||||
{
|
|
||||||
TxPrintf("The box isn't in a window.\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Since the box may actually be in multiple windows, we have to
|
|
||||||
* be a bit careful. If the box is only in one window, then there's
|
|
||||||
* no problem. If it's in more than window, the cursor must
|
|
||||||
* disambiguate the windows.
|
|
||||||
*/
|
|
||||||
|
|
||||||
xMask = ((DBWclientRec *) window->w_clientData)->dbw_bitmask;
|
|
||||||
if ((windowMask & ~xMask) != 0)
|
|
||||||
{
|
|
||||||
window = CmdGetRootPoint((Point *) NULL, (Rect *) NULL);
|
|
||||||
xMask = ((DBWclientRec *) window->w_clientData)->dbw_bitmask;
|
|
||||||
if ((windowMask & xMask) == 0)
|
|
||||||
{
|
|
||||||
TxPrintf("The box is in more than one window; use the cursor\n");
|
|
||||||
TxPrintf("to select the one you want to select from.\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (CmdParseLayers(layers, &mask))
|
|
||||||
{
|
|
||||||
if (TTMaskEqual(&mask, &DBSpaceBits))
|
|
||||||
(void) CmdParseLayers("*,label", &mask);
|
|
||||||
TTMaskClearType(&mask, TT_SPACE);
|
|
||||||
}
|
|
||||||
else return;
|
|
||||||
|
|
||||||
if (less)
|
|
||||||
{
|
|
||||||
(void) SelRemoveArea(&scx.scx_area, &mask);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
scx.scx_use = (CellUse *) window->w_surfaceID;
|
|
||||||
scx.scx_trans = GeoIdentityTransform;
|
|
||||||
crec = (DBWclientRec *) window->w_clientData;
|
|
||||||
SelectArea(&scx, &mask, crec->dbw_bitmask);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ----------------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* cmdSelectVisible --
|
|
||||||
*
|
|
||||||
* This is a utility procedure used by CmdSelect to do area
|
|
||||||
* selection of visible paint.
|
|
||||||
*
|
|
||||||
* Results:
|
|
||||||
* None.
|
|
||||||
*
|
|
||||||
* Side effects:
|
|
||||||
* The selection is augmented to contain all the information on
|
|
||||||
* layers that is visible under the box, including paint, labels,
|
|
||||||
* and expanded subcells.
|
|
||||||
*
|
|
||||||
* ----------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
void
|
|
||||||
cmdSelectVisible(layers, less)
|
|
||||||
char *layers; /* Which layers are to be selected. */
|
char *layers; /* Which layers are to be selected. */
|
||||||
bool less;
|
bool less;
|
||||||
|
int option; /* Option from defined list above */
|
||||||
{
|
{
|
||||||
SearchContext scx;
|
SearchContext scx;
|
||||||
TileTypeBitMask mask;
|
TileTypeBitMask mask;
|
||||||
|
|
@ -680,6 +624,7 @@ cmdSelectVisible(layers, less)
|
||||||
scx.scx_use = (CellUse *) window->w_surfaceID;
|
scx.scx_use = (CellUse *) window->w_surfaceID;
|
||||||
scx.scx_trans = GeoIdentityTransform;
|
scx.scx_trans = GeoIdentityTransform;
|
||||||
crec = (DBWclientRec *) window->w_clientData;
|
crec = (DBWclientRec *) window->w_clientData;
|
||||||
|
if (option == SEL_VISIBLE)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < DBNumUserLayers; i++)
|
for (i = 0; i < DBNumUserLayers; i++)
|
||||||
|
|
@ -688,7 +633,10 @@ cmdSelectVisible(layers, less)
|
||||||
TTMaskClearType(&mask, i);
|
TTMaskClearType(&mask, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SelectArea(&scx, &mask, crec->dbw_bitmask);
|
if (option == SEL_INTERSECT)
|
||||||
|
SelectIntersect(&scx, &mask, crec->dbw_bitmask);
|
||||||
|
else
|
||||||
|
SelectArea(&scx, &mask, crec->dbw_bitmask);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -728,32 +676,13 @@ CmdSelect(w, cmd)
|
||||||
* second table, due to a help message for ":select" with no arguments.
|
* second table, due to a help message for ":select" with no arguments.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define SEL_AREA 0
|
|
||||||
#define SEL_VISIBLE 1
|
|
||||||
#define SEL_CELL 2
|
|
||||||
#define SEL_LABELS 3
|
|
||||||
#define SEL_CLEAR 4
|
|
||||||
#define SEL_FLAT 5
|
|
||||||
#define SEL_HELP 6
|
|
||||||
#define SEL_KEEP 7
|
|
||||||
#define SEL_MOVE 8
|
|
||||||
#define SEL_PICK 9
|
|
||||||
#define SEL_SAVE 10
|
|
||||||
#define SEL_FEEDBACK 11
|
|
||||||
#define SEL_BBOX 12
|
|
||||||
#define SEL_BOX 13
|
|
||||||
#define SEL_CHUNK 14
|
|
||||||
#define SEL_REGION 15
|
|
||||||
#define SEL_NET 16
|
|
||||||
#define SEL_SHORT 17
|
|
||||||
#define SEL_DEFAULT 18
|
|
||||||
|
|
||||||
static char *cmdSelectOption[] =
|
static char *cmdSelectOption[] =
|
||||||
{
|
{
|
||||||
"area",
|
"area",
|
||||||
"visible",
|
"visible",
|
||||||
"cell",
|
"cell",
|
||||||
"labels",
|
"labels",
|
||||||
|
"intersection",
|
||||||
"clear",
|
"clear",
|
||||||
"flat",
|
"flat",
|
||||||
"help",
|
"help",
|
||||||
|
|
@ -780,6 +709,7 @@ CmdSelect(w, cmd)
|
||||||
"[more | less] visible [layers] [de]select all visible info under box in layers",
|
"[more | less] visible [layers] [de]select all visible info under box in layers",
|
||||||
"[more | less | top] cell [name] [de]select cell under cursor, or \"name\"",
|
"[more | less | top] cell [name] [de]select cell under cursor, or \"name\"",
|
||||||
"[do | no] labels [do not] select subcell labels",
|
"[do | no] labels [do not] select subcell labels",
|
||||||
|
"[more | less] intersection [layers] [de]select intersection of layers",
|
||||||
"clear clear selection",
|
"clear clear selection",
|
||||||
"flat flatten the contents of the selection",
|
"flat flatten the contents of the selection",
|
||||||
"help print this message",
|
"help print this message",
|
||||||
|
|
@ -980,7 +910,7 @@ CmdSelect(w, cmd)
|
||||||
}
|
}
|
||||||
if (!(more || less)) SelectClear();
|
if (!(more || less)) SelectClear();
|
||||||
if (cmd->tx_argc == 3)
|
if (cmd->tx_argc == 3)
|
||||||
cmdSelectArea(optionArgs[1], less);
|
cmdSelectArea(optionArgs[1], less, option);
|
||||||
else cmdSelectArea("*,label,subcell", less);
|
else cmdSelectArea("*,label,subcell", less);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -994,8 +924,21 @@ CmdSelect(w, cmd)
|
||||||
if (cmd->tx_argc > 3) goto usageError;
|
if (cmd->tx_argc > 3) goto usageError;
|
||||||
if (!(more || less)) SelectClear();
|
if (!(more || less)) SelectClear();
|
||||||
if (cmd->tx_argc == 3)
|
if (cmd->tx_argc == 3)
|
||||||
cmdSelectVisible(optionArgs[1], less);
|
cmdSelectArea(optionArgs[1], less, option);
|
||||||
else cmdSelectVisible("*,label,subcell", less);
|
else cmdSelectArea("*,label,subcell", less, option);
|
||||||
|
return;
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------
|
||||||
|
* Select area that is the intersection of all the specified layers
|
||||||
|
*--------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
case SEL_INTERSECT:
|
||||||
|
if (cmd->tx_argc > 3) goto usageError;
|
||||||
|
if (!(more || less)) SelectClear();
|
||||||
|
if (cmd->tx_argc == 3)
|
||||||
|
cmdSelectArea(optionArgs[1], less, option);
|
||||||
|
else cmdSelectArea("*,label,subcell", less, option);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/*--------------------------------------------------------------------
|
/*--------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -253,6 +253,205 @@ selClearFunc(scx)
|
||||||
else return 2;
|
else return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Structure used by selIntersectPaintFunc() */
|
||||||
|
|
||||||
|
struct selIntersectData {
|
||||||
|
Rect *sid_rect;
|
||||||
|
TileType sid_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* selDupPaintFunc --
|
||||||
|
*
|
||||||
|
* Copy paint from tile area in Select2Def into SelectDef as all types
|
||||||
|
* in rMask.
|
||||||
|
*
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
selDupPaintFunc(tile, rMask)
|
||||||
|
Tile *tile; /* The tile to get the area to copy paint. */
|
||||||
|
TileTypeBitMask *rMask; /* Paint types to copy to. */
|
||||||
|
{
|
||||||
|
Rect r;
|
||||||
|
|
||||||
|
TiToRect(tile, &r);
|
||||||
|
DBPaintMask(SelectDef, &r, rMask);
|
||||||
|
|
||||||
|
return 0; /* Keep the search going. */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* selIntersectPaintFunc2 ---
|
||||||
|
*
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
selIntersectPaintFunc2(tile, sid)
|
||||||
|
Tile *tile; /* The tile to copy paint from. */
|
||||||
|
struct selIntersectData *sid;
|
||||||
|
{
|
||||||
|
Rect r;
|
||||||
|
int p;
|
||||||
|
|
||||||
|
TiToRect(tile, &r);
|
||||||
|
GEOCLIP(&r, sid->sid_rect); /* Clip out the intersection area */
|
||||||
|
|
||||||
|
DBPaint(Select2Def, &r, sid->sid_type); /* Paint back into Select2Def */
|
||||||
|
|
||||||
|
return 0; /* Keep the search going. */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* selIntersectPaintFunc --
|
||||||
|
*
|
||||||
|
* Erase paint of types in rMask from the area of the tile.
|
||||||
|
*
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
selIntersectPaintFunc(tile, type)
|
||||||
|
Tile *tile; /* The tile to copy paint from. */
|
||||||
|
TileType type; /* The type of tile to keep */
|
||||||
|
{
|
||||||
|
TileTypeBitMask tMask;
|
||||||
|
Rect r;
|
||||||
|
int plane;
|
||||||
|
struct selIntersectData sid;
|
||||||
|
|
||||||
|
TiToRect(tile, &r);
|
||||||
|
|
||||||
|
TTMaskSetOnlyType(&tMask, type);
|
||||||
|
plane = DBPlane(type);
|
||||||
|
|
||||||
|
sid.sid_type = TiGetTypeExact(tile);
|
||||||
|
sid.sid_rect = &r;
|
||||||
|
|
||||||
|
DBSrPaintArea((Tile *)NULL, Select2Def->cd_planes[plane], &r,
|
||||||
|
&tMask, selIntersectPaintFunc2, (ClientData)&sid);
|
||||||
|
|
||||||
|
return 0; /* Keep the search going. */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* SelectIntersect --
|
||||||
|
*
|
||||||
|
* This procedure selects all information that falls in a given area
|
||||||
|
* and contains the intersection of all the supplied types.
|
||||||
|
*
|
||||||
|
* Results:
|
||||||
|
* None.
|
||||||
|
*
|
||||||
|
* Side effects:
|
||||||
|
* The indicated information is added to the select cell, and
|
||||||
|
* outlined on the screen. Only information of particular
|
||||||
|
* types, and in expanded cells (according to xMask) is
|
||||||
|
* selected.
|
||||||
|
*
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
SelectIntersect(scx, types, xMask)
|
||||||
|
SearchContext *scx; /* Describes the area in which material
|
||||||
|
* is to be selected. The resulting
|
||||||
|
* coordinates should map to the coordinates
|
||||||
|
* of EditRootDef. The cell use should be
|
||||||
|
* the root of a window.
|
||||||
|
*/
|
||||||
|
TileTypeBitMask *types; /* Indicates which intersecting layers to
|
||||||
|
* select. May not include labels or cells.
|
||||||
|
*/
|
||||||
|
int xMask; /* Indicates window (or windows) where cells
|
||||||
|
* must be expanded for their contents to be
|
||||||
|
* considered. 0 means treat everything as
|
||||||
|
* expanded.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
TileTypeBitMask tMask, rMask;
|
||||||
|
TileType s, t;
|
||||||
|
int plane;
|
||||||
|
|
||||||
|
/* If the source definition is changing, clear the old selection. */
|
||||||
|
|
||||||
|
if (SelectRootDef != scx->scx_use->cu_def)
|
||||||
|
{
|
||||||
|
if (SelectRootDef != NULL)
|
||||||
|
SelectClear();
|
||||||
|
SelectRootDef = scx->scx_use->cu_def;
|
||||||
|
SelSetDisplay(SelectUse, SelectRootDef);
|
||||||
|
}
|
||||||
|
|
||||||
|
SelRememberForUndo(TRUE, (CellDef *) NULL, (Rect *) NULL);
|
||||||
|
|
||||||
|
/* Select all paint of types in "types" mask and copy into Select2Def */
|
||||||
|
|
||||||
|
DBCellClearDef(Select2Def);
|
||||||
|
(void) DBCellCopyAllPaint(scx, types, xMask, Select2Use);
|
||||||
|
|
||||||
|
/* Find the first type in the list. This will be used as the reference */
|
||||||
|
|
||||||
|
for (t = 0; t < DBNumUserLayers; t++)
|
||||||
|
if (TTMaskHasType(types, t))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (t == DBNumUserLayers) return;
|
||||||
|
|
||||||
|
/* Compute the type mask of the reference type */
|
||||||
|
TTMaskSetOnlyType(&tMask, t);
|
||||||
|
plane = DBPlane(t);
|
||||||
|
|
||||||
|
/* For each other type in "types", do the following */
|
||||||
|
|
||||||
|
for (s = t + 1; s < DBNumUserLayers; s++)
|
||||||
|
{
|
||||||
|
if (TTMaskHasType(types, s))
|
||||||
|
{
|
||||||
|
/* Copy the reference paint type from Select2Def into SelectDef */
|
||||||
|
DBSrPaintArea((Tile *)NULL, Select2Def->cd_planes[plane], &scx->scx_area,
|
||||||
|
&tMask, selDupPaintFunc, (ClientData)&tMask);
|
||||||
|
|
||||||
|
/* Erase the reference paint type from Select2Def */
|
||||||
|
DBEraseMask(Select2Def, &TiPlaneRect, &tMask);
|
||||||
|
|
||||||
|
/* Scan Select2Def for all geometry of type s inside the areas of */
|
||||||
|
/* the reference type, and copy back to Select2Def as the reference */
|
||||||
|
/* type */
|
||||||
|
DBSrPaintArea((Tile *)NULL, SelectDef->cd_planes[plane],
|
||||||
|
&scx->scx_area, &tMask, selIntersectPaintFunc, (ClientData)s);
|
||||||
|
|
||||||
|
/* Erase the reference paint type from SelectDef */
|
||||||
|
DBEraseMask(SelectDef, &TiPlaneRect, &tMask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy any remaining paint in the reference layer in Select2Def to */
|
||||||
|
/* SelectDef as all the intersection types. */
|
||||||
|
|
||||||
|
DBSrPaintArea((Tile *)NULL, Select2Def->cd_planes[plane], &scx->scx_area,
|
||||||
|
&tMask, selDupPaintFunc, (ClientData)types);
|
||||||
|
|
||||||
|
SelectDef->cd_types = *types; /* Remember what types were requested */
|
||||||
|
|
||||||
|
/* Display the new selection. */
|
||||||
|
|
||||||
|
SelRememberForUndo(FALSE, SelectRootDef, &scx->scx_area);
|
||||||
|
DBReComputeBbox(SelectDef);
|
||||||
|
DBWHLRedraw(SelectRootDef, &scx->scx_area, TRUE);
|
||||||
|
DBWAreaChanged(SelectDef, &SelectDef->cd_extended, DBW_ALLWINDOWS,
|
||||||
|
&DBAllButSpaceBits);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ----------------------------------------------------------------------------
|
* ----------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ extern void SelectRegion();
|
||||||
extern void SelectInit();
|
extern void SelectInit();
|
||||||
extern void SelectClear();
|
extern void SelectClear();
|
||||||
extern void SelectCell();
|
extern void SelectCell();
|
||||||
|
extern void SelectIntersect();
|
||||||
extern void SelRemoveArea();
|
extern void SelRemoveArea();
|
||||||
extern int SelRemoveSel2();
|
extern int SelRemoveSel2();
|
||||||
extern int SelectRemoveCellUse();
|
extern int SelectRemoveCellUse();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue