diff --git a/src/db/db/dbRegionProcessors.cc b/src/db/db/dbRegionProcessors.cc index 5931bf3da..f6c1ee9ad 100644 --- a/src/db/db/dbRegionProcessors.cc +++ b/src/db/db/dbRegionProcessors.cc @@ -211,4 +211,36 @@ bool PolygonSizer::result_is_merged () const return (m_dx < 0 && m_dy < 0); } +// ----------------------------------------------------------------------------------- +// TriangulationProcessor implementation + +// some typical value to translate the values into "order of 1" +const double triangulation_dbu = 0.001; + +TriangulationProcessor::TriangulationProcessor (double max_area, double min_b) +{ + m_param.max_area = max_area; + m_param.base_verbosity = 40; + m_param.min_length = 2 * triangulation_dbu; + m_param.min_b = min_b; +} + +void +TriangulationProcessor::process (const db::Polygon &poly, std::vector &result) const +{ + db::Triangles tri; + tri.triangulate (poly, m_param, triangulation_dbu); + + db::Point pts [3]; + auto dbu_trans = db::CplxTrans (triangulation_dbu).inverted (); + + for (auto t = tri.begin (); t != tri.end (); ++t) { + for (int i = 0; i < 3; ++i) { + pts [i] = dbu_trans * *t->vertex (i); + } + result.push_back (db::Polygon ()); + result.back ().assign_hull (pts + 0, pts + 3); + } +} + } diff --git a/src/db/db/dbRegionProcessors.h b/src/db/db/dbRegionProcessors.h index 4bd978193..864289f00 100644 --- a/src/db/db/dbRegionProcessors.h +++ b/src/db/db/dbRegionProcessors.h @@ -28,6 +28,7 @@ #include "dbRegionDelegate.h" #include "dbPolygonTools.h" #include "dbEdgesUtils.h" +#include "dbTriangles.h" namespace db { @@ -405,6 +406,28 @@ private: unsigned int m_mode; }; +/** + * @brief A triangulation processor + */ +class DB_PUBLIC TriangulationProcessor + : public db::PolygonProcessorBase +{ +public: + TriangulationProcessor (double max_area = 0.0, double min_b = 1.0); + + void process (const db::Polygon &poly, std::vector &result) const; + + virtual const TransformationReducer *vars () const { return &m_vars; } + virtual bool result_is_merged () const { return false; } + virtual bool result_must_not_be_merged () const { return false; } + virtual bool requires_raw_input () const { return false; } + virtual bool wants_variants () const { return true; } + +private: + db::Triangles::TriangulateParameters m_param; + db::MagnificationReducer m_vars; +}; + /** * @brief Computes the Minkowski sum between the polygons and the given object * The object can be Edge, Polygon, Box and std::vector diff --git a/src/db/db/gsiDeclDbRegion.cc b/src/db/db/gsiDeclDbRegion.cc index b8c2813ea..04c7b3261 100644 --- a/src/db/db/gsiDeclDbRegion.cc +++ b/src/db/db/gsiDeclDbRegion.cc @@ -235,6 +235,22 @@ static void insert_si2 (db::Region *r, db::RecursiveShapeIterator si, db::ICplxT } } +static db::Region delaunay (const db::Region *r) +{ + db::TriangulationProcessor tri (0.0, 0.0); + db::Region res = r->processed (tri); + res.set_merged_semantics (false); + return res; +} + +static db::Region refined_delaunay (const db::Region *r, double max_area, double min_b) +{ + db::TriangulationProcessor tri (max_area, min_b); + db::Region res = r->processed (tri); + res.set_merged_semantics (false); + return res; +} + static db::Region minkowski_sum_pe (const db::Region *r, const db::Edge &e) { return r->processed (db::minkowski_sum_computation (e)); @@ -2327,6 +2343,37 @@ Class decl_Region (decl_dbShapeCollection, "db", "Region", "\n" "This method has been introduced in version 0.26." ) + + method_ext ("delaunay", &delaunay, + "@brief Computes a constrained Delaunay triangulation from the given region\n" + "\n" + "@return A new region holding the triangles of the constrained Delaunay triangulation.\n" + "\n" + "Note that the result is a region in raw mode as otherwise the triangles are likely to get " + "merged later on.\n" + "\n" + "This method has been introduced in version 0.29." + ) + + method_ext ("delaunay", &refined_delaunay, gsi::arg ("max_area"), gsi::arg ("min_b", 1.0), + "@brief Computes a refined, constrained Delaunay triangulation from the given region\n" + "\n" + "@return A new region holding the triangles of the refined, constrained Delaunay triangulation.\n" + "\n" + "Refinement is implemented by Chew's second algorithm. A maximum area can be given. Triangles " + "larger than this area will be split. In addition 'skinny' triangles will be resolved where " + "possible. 'skinny' is defined in terms of shortest edge to circumcircle radius ratio (b). " + "A minimum number for b can be given. The default of 1.0 corresponds to a minimum angle of 30 degree " + "and is usually a good choice. The algorithm is stable up to roughly 1.2 which corresponds to " + "a minimum angle of abouth 37 degree.\n" + "\n" + "The area value is given in terms of DBU units. Picking a value of 0.0 for area and min b will " + "make the implementation skip the refinement step. In that case, the results are identical to " + "the standard constrained Delaunay triangulation.\n" + "\n" + "Note that the result is a region in raw mode as otherwise the triangles are likely to get " + "merged later on.\n" + "\n" + "This method has been introduced in version 0.29." + ) + method_ext ("minkowski_sum|#minkowsky_sum", &minkowski_sum_pe, gsi::arg ("e"), "@brief Compute the Minkowski sum of the region and an edge\n" "\n"