From 692b1e6c31f8a3c794101fc57e1276651f8b1fd4 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Wed, 6 Sep 2017 23:33:50 +0200 Subject: [PATCH] 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. --- src/edt/edt/edtMainService.cc | 25 +++++++++++++++++++++---- src/edt/edt/edtMainService.h | 5 +++++ src/edt/edt/edtPlugin.cc | 1 + 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/edt/edt/edtMainService.cc b/src/edt/edt/edtMainService.cc index de472949c..9b755565c 100644 --- a/src/edt/edt/edtMainService.cc +++ b/src/edt/edt/edtMainService.cc @@ -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 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::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; diff --git a/src/edt/edt/edtMainService.h b/src/edt/edt/edtMainService.h index 07a2cc084..201884348 100644 --- a/src/edt/edt/edtMainService.h +++ b/src/edt/edt/edtMainService.h @@ -128,6 +128,11 @@ public: */ void cm_intersection (); + /** + * @brief Separation of shapes + */ + void cm_separate (); + /** * @brief Difference of shapes */ diff --git a/src/edt/edt/edtPlugin.cc b/src/edt/edt/edtPlugin.cc index 8e56b8e94..219f482c0 100644 --- a/src/edt/edt/edtPlugin.cc +++ b/src/edt/edt/edtPlugin.cc @@ -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"))));