/* KLayout Layout Viewer Copyright (C) 2006-2017 Matthias Koefferlein This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef HDR_layFinder #define HDR_layFinder #include "laybasicCommon.h" #include #include "tlVector.h" #include "layLayoutView.h" #include "dbBoxConvert.h" #include "dbLayout.h" #include "dbBox.h" #include "dbShape.h" #include "layObjectInstPath.h" namespace tl { class AbsoluteProgress; } namespace lay { // default search range for select in pixels const unsigned int search_range = 5; // TODO make variable? /** * @brief A generic finder class * * A finder traverses the hierarchy and calls the virtual "find" * method on each cell. */ class LAYBASIC_PUBLIC Finder { public: /** * @brief Constructor * * The point_mode is true, if the finder is supposed to operate in "point mode". * In point mode, the center of the search region is the reference point. In * non-point mode, every relevant found inside the search region should be * recorded. * The base class implementation just stores this flag and provides a read * accessor with the point_mode () method. */ Finder (bool point_mode, bool top_level_sel); /** * @brief Destructor (just provided to please the compiler) */ virtual ~Finder (); /** * @brief Proximity getter * * The "proximity" is the closest value passed to the "closer" method. * It returns std::numeric_limits::max () if nothing was found. */ double proximity () const { return m_distance; } protected: const std::vector &layers () const { return m_layers; } bool point_mode () const { return m_point_mode; } const std::vector &path () const { return m_path; } const db::Layout &layout () const { return *mp_layout; } int min_level () const { return m_min_level; } int max_level () const { return m_max_level; } lay::LayoutView *view () const { return mp_view; } bool closer (double d); /** * @brief Start the scan with the given parameters * * Starts the cell scan on the given layout object, with the given region, * starting at the given cell, with the given range of hierarchy levels to * consider and using just the given layer or layers (unless the vector is empty, in which case all layers * are used). For each matching cell, the "visit_cell" method is called. A * path of instantiations up to the top cell is maintained and accessible by * the path() accessor. */ void start (lay::LayoutView *view, const lay::CellView &cv, unsigned int cv_index, const std::vector &trans, const db::Box ®ion, int min_level, int max_level, const std::vector &layers = std::vector ()); /** * @brief Provide a basic edge test facility * * This method computes a "distance" of the edge to the reference point (the * center of the search region). It updates "distance" if the computed distance * is less than the one stored in "distance" or "match" is false. If the * distance is updated, match is set to true. * * This method returns a mask indicating which point of the edge was matching. * Bit 0 of this mask indicates the first point is matching, bit 1 indictates the * second point is matching. */ unsigned int test_edge (const db::Edge &edge, double &distance, bool &match); private: void do_find (const db::Cell &cell, int level, const db::ICplxTrans &t); /** * @brief Visitor sugar function * * This method is supposed to do whatever the finder is supposed to do on the * cell. It may use the "closer" method to determine if something is closer * to whatever. */ virtual void visit_cell (const db::Cell &cell, const db::Box &search_box, const db::ICplxTrans &t, int level) = 0; int m_min_level, m_max_level; std::vector m_path; const db::Layout *mp_layout; lay::LayoutView *mp_view; unsigned int m_cv_index; db::Box m_region; std::vector m_layers; double m_distance; bool m_point_mode; bool m_top_level_sel; db::box_convert m_box_convert; db::box_convert m_cell_box_convert; }; /** * @brief Shape finder utility class * * This class specializes the finder to finding shapes. */ class LAYBASIC_PUBLIC ShapeFinder : public Finder { public: struct StopException { }; typedef std::vector founds_vector_type; typedef founds_vector_type::const_iterator iterator; ShapeFinder (bool point_mode, bool top_level_sel, db::ShapeIterator::flags_type flags, const std::set *excludes = 0); bool find (lay::LayoutView *view, const lay::LayerProperties &lprops, const db::DBox ®ion_mu); bool find (lay::LayoutView *view, const db::DBox ®ion_mu); iterator begin () const { return m_founds.begin (); } iterator end () const { return m_founds.end (); } protected: db::ShapeIterator::flags_type flags () const { return m_flags; } unsigned int cv_index () const { return m_cv_index; } const std::set *prop_sel () const { return mp_prop_sel; } bool inv_prop_sel () const { return m_inv_prop_sel; } db::cell_index_type topcell () const { return m_topcell; } void set_test_count (int n) { m_tries = n; } void checkpoint (); private: virtual void visit_cell (const db::Cell &cell, const db::Box &search_box, const db::ICplxTrans &t, int /*level*/); bool find_internal (lay::LayoutView *view, unsigned int cv_index, const std::set *prop_sel, bool inv_prop_sel, const lay::HierarchyLevelSelection &hier_sel, const std::vector &trans_mu, const std::vector &layers, const db::DBox ®ion_mu); const std::set *mp_excludes; std::vector m_founds; db::ShapeIterator::flags_type m_flags; unsigned int m_cv_index; db::cell_index_type m_topcell; const std::set *mp_prop_sel; bool m_inv_prop_sel; int m_tries; tl::AbsoluteProgress *mp_progress; std::vector m_context_layers; std::map m_cells_with_context; }; /** * @brief Instance finder utility class * * This class specializes the finder to finding instanced. */ class LAYBASIC_PUBLIC InstFinder : public lay::Finder { public: struct StopException { }; typedef std::vector founds_vector_type; typedef founds_vector_type::const_iterator iterator; InstFinder (bool point_mode, bool top_level_sel, bool full_arrays, bool enclose_inst = true, const std::set *excludes = 0, bool visible_layers = false); bool find (lay::LayoutView *view, unsigned int cv_index, const db::DCplxTrans &trans, const db::DBox ®ion_mu); bool find (lay::LayoutView *view, const db::DBox ®ion_mu); iterator begin () const { return m_founds.begin (); } iterator end () const { return m_founds.end (); } private: virtual void visit_cell (const db::Cell &cell, const db::Box &search_box, const db::ICplxTrans &t, int level); bool find_internal (lay::LayoutView *view, unsigned int cv_index, const db::DCplxTrans &trans_mu, const db::DBox ®ion_mu); unsigned int m_cv_index; db::cell_index_type m_topcell; const std::set *mp_excludes; std::vector m_founds; int m_tries; bool m_full_arrays; bool m_enclose_insts; bool m_visible_layers; std::vector m_visible_layer_indexes; lay::LayoutView *mp_view; tl::AbsoluteProgress *mp_progress; }; } #endif