diff --git a/src/edt/edt/gsiDeclEdt.cc b/src/edt/edt/gsiDeclEdt.cc index 9af7a6e8c..e3af87305 100644 --- a/src/edt/edt/gsiDeclEdt.cc +++ b/src/edt/edt/gsiDeclEdt.cc @@ -23,6 +23,7 @@ #include "gsiDecl.h" #include "edtService.h" +#include "dbRecursiveShapeIterator.h" #include "layObjectInstPath.h" #include "layLayoutView.h" @@ -94,7 +95,42 @@ static db::DCplxTrans dtrans (const lay::ObjectInstPath *p) } } +static std::vector get_path (const lay::ObjectInstPath *p) +{ + std::vector pe; + pe.insert (pe.end (), p->begin (), p->end ()); + return pe; +} + +static void set_path (lay::ObjectInstPath *p, const std::vector &pe) +{ + p->assign_path (pe.begin (), pe.end ()); +} + +static lay::ObjectInstPath *from_si (const db::RecursiveShapeIterator &si, int cv_index) +{ + lay::ObjectInstPath *ip = new lay::ObjectInstPath (); + + if (! si.at_end ()) { + + ip->set_cv_index (cv_index); + ip->set_layer (si.layer ()); + ip->set_shape (si.shape ()); + ip->set_topcell (si.top_cell ()->cell_index ()); + std::vector path (si.path ()); + ip->assign_path (path.begin (), path.end ()); + + } + + return ip; +} + gsi::Class decl_ObjectInstPath ("lay", "ObjectInstPath", + gsi::constructor ("new", &from_si, gsi::arg ("si"), gsi::arg ("cv_index"), + "@brief Creates a new path object from a \\RecursiveShapeIterator\n" + "Use this constructor to quickly turn a recursive shape iterator delivery " + "into a shape selection." + ) + gsi::method ("<", &lay::ObjectInstPath::operator<, "@brief Provides an order criterion for two ObjectInstPath objects\n" "@args b\n" @@ -281,7 +317,18 @@ gsi::Class decl_ObjectInstPath ("lay", "ObjectInstPath", "\n" "This method was introduced in version 0.24.\n" ) + - gsi::method ("append_path", (void (lay::ObjectInstPath::*) (const db::InstElement &)) &lay::ObjectInstPath::add_path, + gsi::method_ext ("path", &get_path, + "@brief Gets the instantiation path\n" + "The path is a sequence of \\InstElement objects leading to the target object.\n" + "\n" + "This method was introduced in version 0.26.\n" + ) + + gsi::method_ext ("path=", &set_path, gsi::arg ("p"), + "@brief Sets the instantiation path\n" + "\n" + "This method was introduced in version 0.26.\n" + ) + + gsi::method ("append_path", (void (lay::ObjectInstPath::*) (const db::InstElement &)) &lay::ObjectInstPath::add_path, "@brief Appends an element to the instantiation path\n" "@args element\n" "\n" @@ -528,7 +575,6 @@ static EditableSelectionIterator begin_objects_selected_transient (const lay::La return EditableSelectionIterator (view->get_plugins (), true); } - static gsi::ClassExt layout_view_decl ( gsi::method_ext ("has_object_selection?", &has_object_selection, diff --git a/src/klayout.pro b/src/klayout.pro index e208dd664..2ecee1271 100644 --- a/src/klayout.pro +++ b/src/klayout.pro @@ -99,6 +99,3 @@ plugins.depends += lib rdb db } unit_tests.depends += plugins $$MAIN_DEPENDS - -RESOURCES += \ - laybasic/laybasic/layResources.qrc diff --git a/src/laybasic/laybasic/layBitmapRenderer.cc b/src/laybasic/laybasic/layBitmapRenderer.cc index 7259551fb..fd47637f2 100644 --- a/src/laybasic/laybasic/layBitmapRenderer.cc +++ b/src/laybasic/laybasic/layBitmapRenderer.cc @@ -161,53 +161,35 @@ BitmapRenderer::insert (const db::DEdge &e) m_edges.push_back (e); } +static inline bool point_inside_box (const db::DPoint &pt, const db::DBox &box) +{ + return (! (db::coord_traits::equal (pt.x (), box.left ()) || db::coord_traits::equal (pt.x (), box.right ())) && + ! (db::coord_traits::equal (pt.y (), box.bottom ()) || db::coord_traits::equal (pt.y (), box.top ()))); +} + void BitmapRenderer::add_xfill () { - bool any = false; - db::DPoint a1, a2, b1, b2; - const double eps = 1e-10; - + db::DBox box; for (std::vector::const_iterator e = m_edges.begin (); e != m_edges.end (); ++e) { - - db::DPoint p1 = e->p1 (); - - if (!any) { - - a1 = a2 = b1 = b2 = p1; - any = true; - - } else { - - db::DVector d; - - d = p1 - a1; - if (d.x () - d.y () < -eps) { - a1 = p1; - } - - d = p1 - a2; - if (d.x () - d.y () > eps) { - a2 = p1; - } - - d = p1 - b1; - if (d.x () + d.y () < -eps) { - b1 = p1; - } - - d = p1 - b2; - if (d.x () + d.y () > eps) { - b2 = p1; - } - + if (! e->is_ortho ()) { + return; } - + box += e->p1 (); + box += e->p2 (); } - if (any) { - insert (db::DEdge (a1, a2)); - insert (db::DEdge (b1, b2)); + if (! box.empty () && box.area () > 0.0) { + + for (std::vector::const_iterator e = m_edges.begin (); e != m_edges.end (); ++e) { + if (point_inside_box (e->p1 (), box) || point_inside_box (e->p2 (), box)) { + return; + } + } + + insert (db::DEdge (box.p1 (), box.p2 ())); + insert (db::DEdge (box.lower_right (), box.upper_left ())); + } } @@ -483,6 +465,9 @@ BitmapRenderer::draw (const db::Shape &shape, const db::CplxTrans &trans, render_fill (*fill); } if (frame) { + if (m_xfill) { + add_xfill (); + } render_contour (*frame); } diff --git a/testdata/ruby/edtTest.rb b/testdata/ruby/edtTest.rb index 6708c6b6a..2ee85bc55 100644 --- a/testdata/ruby/edtTest.rb +++ b/testdata/ruby/edtTest.rb @@ -109,6 +109,16 @@ class EDT_TestClass < TestBase assert_equal(p.trans.to_s, "r0 *1 0,0") assert_equal(p.source_trans.to_s, "r0 *1 0,0") + # ObjectInstPath from RecursiveShapeIterator + + si = tc.begin_shapes_rec(li) + oi = RBA::ObjectInstPath::new(si, 2) + + assert_equal(oi.cv_index, 2) + assert_equal(oi.shape.to_s, si.shape.to_s) + assert_equal(oi.cell_index, si.cell.cell_index) + assert_equal(oi.top, tc.cell_index) + end # Selection