A new function to separate inside/outside

- This feature is found in Edit/Selection/Separate
  The first selection is separated into parts inside and
  outside the secondary selection

In addition, shapes are not deleted on the boolean
(selection-based) functions if they come from a different
layer than the primary selection.
This commit is contained in:
Matthias Koefferlein 2017-09-06 23:33:50 +02:00
parent 5221027b3a
commit 692b1e6c31
3 changed files with 27 additions and 4 deletions

View File

@ -95,6 +95,8 @@ MainService::menu_activated (const std::string &symbol)
cm_union ();
} else if (symbol == "edt::sel_intersection") {
cm_intersection ();
} else if (symbol == "edt::sel_separate") {
cm_separate ();
} else if (symbol == "edt::sel_difference") {
cm_difference ();
} else if (symbol == "edt::sel_change_layer") {
@ -1554,15 +1556,24 @@ MainService::boolean_op (int mode)
std::vector <db::Polygon> out;
db::EdgeProcessor ep;
ep.boolean (primary, secondary, out, mode);
if (mode == -1 /*== separate*/) {
ep.boolean (primary, secondary, out, db::BooleanOp::And);
ep.boolean (primary, secondary, out, db::BooleanOp::ANotB);
} else {
ep.boolean (primary, secondary, out, mode);
}
view ()->cancel_edits ();
manager ()->transaction (tl::to_string (QObject::tr ("Boolean operation on selection")));
// Delete the current selection
// NOTE: we delete only those shapes from the primary layer and keep shapes from other layers.
// Let's see whether this heuristics is more accepted.
for (std::vector<edt::Service *>::const_iterator es = edt_services.begin (); es != edt_services.end (); ++es) {
for (edt::Service::obj_iterator s = (*es)->selection ().begin (); s != (*es)->selection ().end (); ++s) {
if (! s->is_cell_inst () && (s->shape ().is_polygon () || s->shape ().is_path () || s->shape ().is_box ())) {
if (int (s->layer ()) == layer_index && ! s->is_cell_inst () && (s->shape ().is_polygon () || s->shape ().is_path () || s->shape ().is_box ())) {
db::Cell &cell = view ()->cellview (s->cv_index ())->layout ().cell (s->cell_index ());
if (cell.shapes (s->layer ()).is_valid (s->shape ())) {
cell.shapes (s->layer ()).erase_shape (s->shape ());
@ -1612,13 +1623,19 @@ MainService::cm_intersection ()
boolean_op (db::BooleanOp::And);
}
void
void
MainService::cm_difference ()
{
boolean_op (db::BooleanOp::ANotB);
}
static
void
MainService::cm_separate ()
{
boolean_op (-1); // == separate (And + ANotB)
}
static
db::DVector compute_alignment_vector (const db::DBox &prim_box, const db::DBox &box, int hmode, int vmode)
{
double dx = 0.0;

View File

@ -128,6 +128,11 @@ public:
*/
void cm_intersection ();
/**
* @brief Separation of shapes
*/
void cm_separate ();
/**
* @brief Difference of shapes
*/

View File

@ -230,6 +230,7 @@ public:
menu_entries.push_back (lay::MenuEntry ("edt::sel_union", "union:edit_mode", "edit_menu.selection_menu.end", tl::to_string (QObject::tr ("Merge Shapes"))));
menu_entries.push_back (lay::MenuEntry ("edt::sel_intersection", "intersection:edit_mode", "edit_menu.selection_menu.end", tl::to_string (QObject::tr ("Intersection - Others With First"))));
menu_entries.push_back (lay::MenuEntry ("edt::sel_difference", "difference:edit_mode", "edit_menu.selection_menu.end", tl::to_string (QObject::tr ("Subtraction - Others From First"))));
menu_entries.push_back (lay::MenuEntry ("edt::sel_separate", "separate:edit_mode", "edit_menu.selection_menu.end", tl::to_string (QObject::tr ("Separate - First into Inside/Outside Others"))));
menu_entries.push_back (lay::MenuEntry ("hier_group:edit_mode", "edit_menu.selection_menu.end"));
menu_entries.push_back (lay::MenuEntry ("edt::sel_flatten_insts", "flatten_insts:edit_mode", "edit_menu.selection_menu.end", tl::to_string (QObject::tr ("Flatten Instances"))));
menu_entries.push_back (lay::MenuEntry ("edt::sel_resolve_arefs", "resolve_arefs:edit_mode", "edit_menu.selection_menu.end", tl::to_string (QObject::tr ("Resolve Arrays"))));