From 495da3de23022ba5f1ddd9b70f221231dfef64dc Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sat, 12 Aug 2023 00:46:23 +0200 Subject: [PATCH] WIP --- src/db/db/db.pro | 4 + src/db/db/dbTriangle.cc | 406 ++++++++++++++++++++++++++ src/db/db/dbTriangle.h | 388 ++++++++++++++++++++++++ src/db/db/dbTriangles.cc | 24 ++ src/db/db/dbTriangles.h | 39 +++ src/db/unit_tests/dbTriangleTests.cc | 30 ++ src/db/unit_tests/dbTrianglesTests.cc | 30 ++ src/db/unit_tests/unit_tests.pro | 2 + 8 files changed, 923 insertions(+) create mode 100644 src/db/db/dbTriangle.cc create mode 100644 src/db/db/dbTriangle.h create mode 100644 src/db/db/dbTriangles.cc create mode 100644 src/db/db/dbTriangles.h create mode 100644 src/db/unit_tests/dbTriangleTests.cc create mode 100644 src/db/unit_tests/dbTrianglesTests.cc diff --git a/src/db/db/db.pro b/src/db/db/db.pro index 6914e12fa..28201ab1c 100644 --- a/src/db/db/db.pro +++ b/src/db/db/db.pro @@ -95,6 +95,8 @@ SOURCES = \ dbTextWriter.cc \ dbTilingProcessor.cc \ dbTrans.cc \ + dbTriangle.cc \ + dbTriangles.cc \ dbUserObject.cc \ dbUtils.cc \ dbVector.cc \ @@ -319,6 +321,8 @@ HEADERS = \ dbTextWriter.h \ dbTilingProcessor.h \ dbTrans.h \ + dbTriangle.h \ + dbTriangles.h \ dbTypes.h \ dbUserObject.h \ dbUtils.h \ diff --git a/src/db/db/dbTriangle.cc b/src/db/db/dbTriangle.cc new file mode 100644 index 000000000..babc271fa --- /dev/null +++ b/src/db/db/dbTriangle.cc @@ -0,0 +1,406 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2023 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 + +*/ + + +#include "dbTriangle.h" + +#include + +namespace db +{ + +// ------------------------------------------------------------------------------------- +// Vertex implementation + +Vertex::Vertex () + : DPoint (), m_level (0) +{ + // .. nothing yet .. +} + +Vertex::Vertex (const db::DPoint &p) + : DPoint (p), m_level (0) +{ + // .. nothing yet .. +} + +Vertex::Vertex (db::DCoord x, db::DCoord y) + : DPoint (x, y), m_level (0) +{ + // .. nothing yet .. +} + +bool +Vertex::is_outside () const +{ + for (auto e = m_edges.begin (); e != m_edges.end (); ++e) { + if (e->is_outside ()) { + return true; + } + } + return false; +} + +std::vector +Vertex::triangles () const +{ + std::set seen; + std::vector res; + for (auto e = m_edges.begin (); e != m_edges.end (); ++e) { + for (auto t = e->begin_triangles (); t != e->end_triangles (); ++t) { + if (seen.insert (t.operator-> ()).second) { + res.push_back (t.operator-> ()); + } + } + } + return res; +} + +std::string +Vertex::to_string () const +{ + return db::DPoint::to_string () + tl::sprintf ("[%p]", (void *)this); +} + +// ------------------------------------------------------------------------------------- +// TriangleEdge implementation + +TriangleEdge::TriangleEdge () + : mp_v1 (0), mp_v2 (0), mp_left (), mp_right (), m_level (0), m_is_segment (false) +{ + // .. nothing yet .. +} + +TriangleEdge::TriangleEdge (Vertex *v1, Vertex *v2) + : mp_v1 (v1), mp_v2 (v2), mp_left (), mp_right (), m_level (0), m_is_segment (false) +{ + // .. nothing yet .. +} + +Triangle * +TriangleEdge::other (const Triangle *t) const +{ + if (t == mp_left.get ()) { + return const_cast (mp_right.get ()); + } + if (t == mp_right.get ()) { + return const_cast (mp_left.get ()); + } + tl_assert (false); + return 0; +} + +Vertex * +TriangleEdge::other (const Vertex *t) const +{ + if (t == mp_v1) { + return mp_v2; + } + if (t == mp_v2) { + return mp_v1; + } + tl_assert (false); + return 0; +} + +bool +TriangleEdge::has_vertex (const Vertex *v) const +{ + return mp_v1 == v || mp_v2 == v; +} + +Vertex * +TriangleEdge::common_vertex (const TriangleEdge &other) const +{ + if (has_vertex (other.v1 ())) { + return (other.v1 ()); + } + if (has_vertex (other.v2 ())) { + return (other.v2 ()); + } + return 0; +} + +std::string +TriangleEdge::to_string () const +{ + return mp_v1->to_string () + "," + mp_v2->to_string () + tl::sprintf ("[%p]", (void *)this); +} + +double +TriangleEdge::distance (const db::DEdge &e, const db::DPoint &p) +{ + double l = db::sprod (p - e.p1 (), e.d ()) / e.d ().sq_length (); + db::DPoint pp; + if (l <= 0.0) { + pp = e.p1 (); + } else if (l >= 1.0) { + pp = e.p2 (); + } else { + pp = e.p1 () + e.d () * l; + } + return (p - pp).length (); +} + +bool +TriangleEdge::crosses (const db::DEdge &e, const db::DEdge &other) +{ + return e.side_of (other.p1 ()) * e.side_of (other.p2 ()) < 0 && + other.side_of (e.p1 ()) * other.side_of (e.p2 ()) < 0; +} + +bool +TriangleEdge::crosses_including (const db::DEdge &e, const db::DEdge &other) +{ + return e.side_of (other.p1 ()) * e.side_of (other.p2 ()) <= 0 && + other.side_of (e.p1 ()) * other.side_of (e.p2 ()) <= 0; +} + +db::DPoint +TriangleEdge::intersection_point (const db::DEdge &e, const db::DEdge &other) +{ + return e.intersect_point (other).second; +} + +bool +TriangleEdge::point_on (const db::DEdge &edge, const db::DPoint &point) +{ + if (edge.side_of (point) != 0) { + return false; + } else { + return db::sprod_sign (point - edge.p1 (), edge.d ()) * db::sprod_sign(point - edge.p2 (), edge.d ()) < 0; + } +} + +bool +TriangleEdge::can_flip () const +{ + if (! left () || ! right ()) { + return false; + } + + const db::Vertex *v1 = left ()->opposite (this); + const db::Vertex *v2 = right ()->opposite (this); + return crosses (db::DEdge (*v1, *v2)); +} + +bool +TriangleEdge::can_join_via (const Vertex *vertex) const +{ + if (! left () || ! right ()) { + return false; + } + + tl_assert (has_vertex (vertex)); + const db::Vertex *v1 = left ()->opposite (this); + const db::Vertex *v2 = right ()->opposite (this); + return db::DEdge (*v1, *v2).side_of (*vertex) == 0; +} + +bool +TriangleEdge::is_outside () const +{ + return left () == 0 || right () == 0; +} + +bool +TriangleEdge::is_for_outside_triangles () const +{ + return (left () && left ()->is_outside ()) || (right () && right ()->is_outside ()); +} + +bool +TriangleEdge::has_triangle (const Triangle *t) const +{ + return t != 0 && (left () == t || right () == t); +} + +// ------------------------------------------------------------------------------------- +// Triangle implementation + +Triangle::Triangle () + : m_is_outside (false), mp_v1 (0), mp_v2 (0), mp_v3 (0) +{ + // .. nothing yet .. +} + +Triangle::Triangle (TriangleEdge *e1, TriangleEdge *e2, TriangleEdge *e3) + : m_is_outside (false), mp_e1 (e1), mp_e2 (e2), mp_e3 (e3) +{ + mp_v1 = e1->v1 (); + mp_v2 = e1->other (mp_v1); + + if (e2->has_vertex (mp_v2)) { + mp_v3 = e2->other (mp_v2); + tl_assert (e3->other (mp_v3) == mp_v1); + } else { + mp_v3 = e3->other (mp_v2); + tl_assert (e2->other (mp_v3) == mp_v1); + } + + // enforce clockwise orientation + if (db::vprod_sign (*mp_v3 - *mp_v1, *mp_v2 - *mp_v1) < 0) { + std::swap (mp_v3, mp_v2); + } + + // establish link to edges + for (int i = 0; i < 3; ++i) { + TriangleEdge *e = edge (i); + int side_of = 0; + for (int j = 0; j < 3; ++j) { + side_of += e->side_of (*vertex (j)); + } + // NOTE: in the degenerated case, the triangle is not attached to an edge! + if (side_of < 0) { + e->set_left (this); + } else if (side_of > 0) { + e->set_right (this); + } + } +} + +std::string +Triangle::to_string () const +{ + std::string res; + for (int i = 0; i < 3; ++i) { + if (i > 0) { + res += ", "; + } + if (vertex (i)) { + res += vertex (i)->to_string (); + } else { + res += "(null)"; + } + } + return res; +} + +Vertex * +Triangle::vertex (int n) const +{ + tl_assert (mp_e1 && mp_e2 && mp_e3); + n = (n + 3) % 3; + if (n == 0) { + return mp_v1; + } else if (n == 1) { + return mp_v2; + } else { + return mp_v3; + } +} + +TriangleEdge * +Triangle::edge (int n) const +{ + n = (n + 3) % 3; + if (n == 0) { + return const_cast (mp_e1.get ()); + } else if (n == 1) { + return const_cast (mp_e2.get ()); + } else { + return const_cast (mp_e3.get ()); + } +} + +double +Triangle::area () const +{ + return fabs (db::vprod (mp_e1->d (), mp_e2->d ())) * 0.5; +} + +std::pair +Triangle::circumcircle () const +{ + db::DVector v1 = *vertex(0) - *vertex(1); + db::DVector v2 = *vertex(0) - *vertex(2); + db::DVector n1 = db::DVector (v1.y (), -v1.x ()); + db::DVector n2 = db::DVector (v2.y (), -v2.x ()); + + double p1s = vertex(0)->sq_distance (db::DPoint ()); + double p2s = vertex(1)->sq_distance (db::DPoint ()); + double p3s = vertex(2)->sq_distance (db::DPoint ()); + + double s = db::vprod (v1, v2); + tl_assert (fabs (s) > db::epsilon); + + db::DPoint center = db::DPoint () + (n2 * (p1s - p2s) - n1 * (p1s - p3s)) * (0.5 / s); + double radius = (*vertex (0) - center).length (); + + return std::make_pair (center, radius); +} + +Vertex * +Triangle::opposite (const TriangleEdge *edge) const +{ + for (int i = 0; i < 3; ++i) { + Vertex *v = vertex (i); + if (! edge->has_vertex (v)) { + return v; + } + } + tl_assert (false); +} + +TriangleEdge * +Triangle::opposite (const Vertex *vertex) const +{ + for (int i = 0; i < 3; ++i) { + TriangleEdge *e = edge (i); + if (! e->has_vertex (vertex)) { + return e; + } + } + tl_assert (false); +} + +TriangleEdge * +Triangle::find_edge_with (const Vertex *v1, const Vertex *v2) const +{ + for (int i = 0; i < 3; ++i) { + TriangleEdge *e = edge (i); + if (e->has_vertex (v1) && e->has_vertex (v2)) { + return e; + } + } + tl_assert (false); +} + +int +Triangle::contains (const db::DPoint &point) const +{ + int res = 1; + const Vertex *vl = vertex (-1); + for (int i = 0; i < 3; ++i) { + const Vertex *v = vertex (i); + int s = db::DEdge (*vl, *v).side_of (point); + if (s == 0) { + res = 0; + } else if (s < 0) { + return -1; + } + vl = v; + } + return res; +} + +} diff --git a/src/db/db/dbTriangle.h b/src/db/db/dbTriangle.h new file mode 100644 index 000000000..e5ee02c3f --- /dev/null +++ b/src/db/db/dbTriangle.h @@ -0,0 +1,388 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2023 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_dbTriangle +#define HDR_dbTriangle + +#include "dbCommon.h" +#include "dbPoint.h" +#include "dbEdge.h" + +#include "tlObjectCollection.h" + +namespace db +{ + +class Triangle; +class TriangleEdge; + +/** + * @brief A class representing a vertex in a Delaunay triangulation graph + * + * The vertex carries information about the connected edges and + * an integer value that can be used in traversal algorithms + * ("level") + */ +class Vertex + : public db::DPoint +{ +public: + typedef tl::weak_collection edges_type; + typedef edges_type::const_iterator edges_iterator; + + Vertex (); + Vertex (const DPoint &p); + Vertex (db::DCoord x, db::DCoord y); + + bool is_outside () const; + std::vector triangles () const; + + edges_iterator begin_edges () const { return m_edges.begin (); } + edges_iterator end_edges () const { return m_edges.end (); } + + size_t level () const { return m_level; } + void set_level (size_t l) { m_level = l; } + + std::string to_string () const; + +private: + edges_type m_edges; + size_t m_level; +}; + +/** + * @brief A class representing an edge in the Delaunay triangulation graph + */ +class TriangleEdge + : public tl::Object +{ +public: + class TriangleIterator + { + public: + typedef Triangle value_type; + typedef Triangle &reference; + typedef Triangle *pointer; + + reference operator*() const + { + return *operator-> (); + } + + pointer operator->() const + { + return m_index ? mp_edge->right () : mp_edge->left (); + } + + bool operator== (const TriangleIterator &other) const + { + return mp_edge == other.mp_edge && m_index == other.m_index; + } + + bool operator!= (const TriangleIterator &other) const + { + return !operator== (other); + } + + TriangleIterator &operator++ () + { + while (++m_index < 2 && operator-> () == 0) + ; + return *this; + } + + private: + friend class TriangleEdge; + + TriangleIterator (const TriangleEdge *edge) + : mp_edge (edge), m_index (0) + { + if (! edge) { + m_index = 2; + } else { + --m_index; + operator++ (); + } + } + + const TriangleEdge *mp_edge; + unsigned int m_index; + }; + + TriangleEdge (); + TriangleEdge (Vertex *v1, Vertex *v2); + + Vertex *v1 () const { return mp_v1; } + Vertex *v2 () const { return mp_v2; } + + Triangle *left () const { return const_cast (mp_left.get ()); } + Triangle *right () const { return const_cast (mp_right.get ()); } + void set_left (Triangle *t) { mp_left = t; } + void set_right (Triangle *t) { mp_right = t; } + + TriangleIterator begin_triangles () const + { + return TriangleIterator (this); + } + + TriangleIterator end_triangles () const + { + return TriangleIterator (0); + } + + void set_level (size_t l) { m_level = l; } + size_t level () const { return m_level; } + + void set_is_segment (bool is_seg) { m_is_segment = is_seg; } + bool is_segment () const { return m_is_segment; } + + std::string to_string () const; + + /** + * @brief Converts to an db::DEdge + */ + db::DEdge edge () const + { + return db::DEdge (*mp_v1, *mp_v2); + } + + /** + * @brief Returns the distance of the given point to the edge + * + * The distance is the minimum distance of the point to one point from the edge. + * @@@ TODO: Move to db::DEdge + */ + static double distance (const db::DEdge &e, const db::DPoint &p); + + /** + * @brief Returns the distance of the given point to the edge + * + * The distance is the minimum distance of the point to one point from the edge. + */ + double distance (const db::DPoint &p) const + { + return distance (edge (), p); + } + + /** + * @brief Returns a value indicating wether this edge crosses the other one + * + * "crosses" is true, if both edges share at least one point which is not an endpoint + * of one of the edges. + * @@@ TODO: Move to db::DEdge + */ + static bool crosses (const db::DEdge &e, const db::DEdge &other); + + /** + * @brief Returns a value indicating wether this edge crosses the other one + * + * "crosses" is true, if both edges share at least one point which is not an endpoint + * of one of the edges. + */ + bool crosses (const db::DEdge &other) const + { + return crosses (edge (), other); + } + + /** + * @brief Returns a value indicating wether this edge crosses the other one + * "crosses" is true, if both edges share at least one point. + * @@@ TODO: Move to db::DEdge + */ + static bool crosses_including (const db::DEdge &e, const db::DEdge &other); + + /** + * @brief Returns a value indicating wether this edge crosses the other one + * "crosses" is true, if both edges share at least one point. + */ + bool crosses_including (const db::DEdge &other) const + { + return crosses_including (edge (), other); + } + + /** + * @brief Gets the intersection point + * @@@ TODO: Move to db::DEdge + */ + static db::DPoint intersection_point (const db::DEdge &e, const DEdge &other); + + /** + * @brief Gets the intersection point + */ + db::DPoint intersection_point (const db::DEdge &other) const + { + return intersection_point (edge (), other); + } + + /** + * @brief Returns a value indicating whether the point is on the edge + * @@@ TODO: Move to db::DEdge + */ + static bool point_on (const db::DEdge &edge, const db::DPoint &point); + + /** + * @brief Returns a value indicating whether the point is on the edge + */ + bool point_on (const db::DPoint &point) const + { + return point_on (edge (), point); + } + + /** + * @brief Gets the side the point is on + * + * -1 is for "left", 0 is "on" and +1 is "right" + */ + int side_of (const db::DPoint &p) const + { + return edge ().side_of (p); + } + + /** + * @brief Gets the distance vector + */ + db::DVector d () const + { + return *mp_v2 - *mp_v1; + } + + /** + * @brief Gets the other triangle for the given one + */ + Triangle *other (const Triangle *) const; + + /** + * @brief Gets the other vertex for the given one + */ + Vertex *other (const Vertex *) const; + + /** + * @brief Gets a value indicating whether the edge has the given vertex + */ + bool has_vertex (const Vertex *) const; + + /** + * @brief Gets the common vertex of the other edge and this edge or null if there is no common vertex + */ + Vertex *common_vertex (const TriangleEdge &other) const; + + /** + * @brief Returns a value indicating whether this edge can be flipped + */ + bool can_flip () const; + + /** + * @brief Returns a value indicating whether the edge separates two triangles that can be joined into one (via the given vertex) + */ + bool can_join_via (const Vertex *vertex) const; + + /** + * @brief Returns a value indicating whether this edge is an outside edge (no other triangles) + */ + bool is_outside () const; + + /** + * @brief Returns a value indicating whether this edge belongs to outside triangles + */ + bool is_for_outside_triangles () const; + + /** + * @brief Returns a value indicating whether t is attached to this edge + */ + bool has_triangle (const Triangle *t) const; + +private: + Vertex *mp_v1, *mp_v2; + tl::weak_ptr mp_left, mp_right; + size_t m_level; + bool m_is_segment; +}; + +/** + * @brief A class representing a triangle + */ +class Triangle + : public tl::Object +{ +public: + Triangle (); + Triangle (TriangleEdge *e1, TriangleEdge *e2, TriangleEdge *e3); + + bool is_outside () const { return m_is_outside; } + void set_outside (bool o) { m_is_outside = o; } + + std::string to_string () const; + + /** + * @brief Gets the nth vertex (n wraps around and can be negative) + * The vertexes are oriented clockwise. + */ + Vertex *vertex (int n) const; + + /** + * @brief Gets the nth edge (n wraps around and can be negative) + */ + TriangleEdge *edge (int n) const; + + /** + * @brief Gets the area + */ + double area () const; + + /** + * @brief Gets the center point and radius of the circumcircle + */ + std::pair circumcircle () const; + + /** + * @brief Gets the vertex opposite of the given edge + */ + Vertex *opposite (const TriangleEdge *edge) const; + + /** + * @brief Gets the edge opposite of the given vertex + */ + TriangleEdge *opposite (const Vertex *vertex) const; + + /** + * @brief Gets the edge with the given vertexes + */ + TriangleEdge *find_edge_with (const Vertex *v1, const Vertex *v2) const; + + /** + * @brief Returns a value indicating whether the point is inside (1), on the triangle (0) or outside (-1) + */ + int contains (const db::DPoint &point) const; + +private: + bool m_is_outside; + tl::weak_ptr mp_e1, mp_e2, mp_e3; + db::Vertex *mp_v1, *mp_v2, *mp_v3; +}; + + +} + +#endif + diff --git a/src/db/db/dbTriangles.cc b/src/db/db/dbTriangles.cc new file mode 100644 index 000000000..529e35c63 --- /dev/null +++ b/src/db/db/dbTriangles.cc @@ -0,0 +1,24 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2023 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 + +*/ + + +#include "dbTriangles.h" diff --git a/src/db/db/dbTriangles.h b/src/db/db/dbTriangles.h new file mode 100644 index 000000000..b81790b13 --- /dev/null +++ b/src/db/db/dbTriangles.h @@ -0,0 +1,39 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2023 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_dbTriangles +#define HDR_dbTriangles + +#include "dbCommon.h" + +namespace db +{ + + + + +} + +#endif + diff --git a/src/db/unit_tests/dbTriangleTests.cc b/src/db/unit_tests/dbTriangleTests.cc new file mode 100644 index 000000000..a9be821e0 --- /dev/null +++ b/src/db/unit_tests/dbTriangleTests.cc @@ -0,0 +1,30 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2023 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 + +*/ + + +#include "dbTriangle.h" +#include "tlUnitTest.h" + +TEST(1) +{ + +} diff --git a/src/db/unit_tests/dbTrianglesTests.cc b/src/db/unit_tests/dbTrianglesTests.cc new file mode 100644 index 000000000..25b24bbb3 --- /dev/null +++ b/src/db/unit_tests/dbTrianglesTests.cc @@ -0,0 +1,30 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2023 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 + +*/ + + +#include "dbTriangles.h" +#include "tlUnitTest.h" + +TEST(1) +{ + +} diff --git a/src/db/unit_tests/unit_tests.pro b/src/db/unit_tests/unit_tests.pro index 351bf8860..e1544fcf8 100644 --- a/src/db/unit_tests/unit_tests.pro +++ b/src/db/unit_tests/unit_tests.pro @@ -11,6 +11,8 @@ SOURCES = \ dbFillToolTests.cc \ dbRecursiveInstanceIteratorTests.cc \ dbRegionCheckUtilsTests.cc \ + dbTriangleTests.cc \ + dbTrianglesTests.cc \ dbUtilsTests.cc \ dbWriterTools.cc \ dbLoadLayoutOptionsTests.cc \