// David Eberly, Geometric Tools, Redmond WA 98052 // Copyright (c) 1998-2021 // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt // https://www.geometrictools.com/License/Boost/LICENSE_1_0.txt // Version: 4.0.2019.08.13 #pragma once #include namespace gte { template class Delaunay2Mesh {}; } namespace gte { // The InputType is 'float' or 'double'. The ComputeType can be a // floating-point type or BSNumber<*> type, because it does not require // divisions. The RationalType requires division, so you can use // BSRational<*>. template class // [[deprecated("Use Delaunay2Mesh instead.")]] Delaunay2Mesh { public: // Construction. Delaunay2Mesh(Delaunay2 const& delaunay) : mDelaunay(&delaunay) { } // Mesh information. inline int GetNumVertices() const { return mDelaunay->GetNumVertices(); } inline int GetNumTriangles() const { return mDelaunay->GetNumTriangles(); } inline Vector2 const* GetVertices() const { return mDelaunay->GetVertices(); } inline int const* GetIndices() const { return &mDelaunay->GetIndices()[0]; } inline int const* GetAdjacencies() const { return &mDelaunay->GetAdjacencies()[0]; } inline int GetInvalidIndex() const { return mDelaunay->negOne; } // Containment queries. int GetContainingTriangle(Vector2 const& P) const { // VS 2019 16.8.1 generates LNT1006 "Local variable is not // initialized." Incorrect, because the default constructor // initializes all the members. typename Delaunay2::SearchInfo info; return mDelaunay->GetContainingTriangle(P, info); } bool GetVertices(int t, std::array, 3>& vertices) const { if (mDelaunay->GetDimension() == 2) { std::array indices = { 0, 0, 0 }; if (mDelaunay->GetIndices(t, indices)) { PrimalQuery2 const& query = mDelaunay->GetQuery(); Vector2 const* ctVertices = query.GetVertices(); for (int i = 0; i < 3; ++i) { Vector2 const& V = ctVertices[indices[i]]; for (int j = 0; j < 2; ++j) { vertices[i][j] = (InputType)V[j]; } } return true; } } return false; } bool GetIndices(int t, std::array& indices) const { return mDelaunay->GetIndices(t, indices); } bool GetAdjacencies(int t, std::array& adjacencies) const { return mDelaunay->GetAdjacencies(t, adjacencies); } bool GetBarycentrics(int t, Vector2 const& P, std::array& bary) const { std::array indices = { 0, 0, 0 }; if (mDelaunay->GetIndices(t, indices)) { PrimalQuery2 const& query = mDelaunay->GetQuery(); Vector2 const* vertices = query.GetVertices(); Vector2 rtP{ P[0], P[1] }; std::array, 3> rtV; for (int i = 0; i < 3; ++i) { Vector2 const& V = vertices[indices[i]]; for (int j = 0; j < 2; ++j) { rtV[i][j] = (RationalType)V[j]; } }; std::array rtBary; if (ComputeBarycentrics(rtP, rtV[0], rtV[1], rtV[2], rtBary.data())) { for (int i = 0; i < 3; ++i) { bary[i] = (InputType)rtBary[i]; } return true; } } return false; } private: Delaunay2 const* mDelaunay; }; } namespace gte { // The input type T is 'float' or 'double'. template class Delaunay2Mesh { public: // Construction. Delaunay2Mesh(Delaunay2 const& delaunay) : mDelaunay(&delaunay) { } // Mesh information. inline size_t GetNumVertices() const { return mDelaunay->GetNumVertices(); } inline size_t GetNumTriangles() const { return mDelaunay->GetNumTriangles(); } inline std::vector> const* GetVertices() const { return mDelaunay->GetVertices(); } inline std::vector const& GetIndices() const { return mDelaunay->GetIndices(); } inline std::vector const& GetAdjacencies() const { return mDelaunay->GetAdjacencies(); } // Containment queries. size_t GetContainingTriangle(Vector2 const& P) const { // VS 2019 16.8.1 generates LNT1006 "Local variable is not // initialized." Incorrect, because the default constructor // initializes all the members. typename Delaunay2::SearchInfo info; return mDelaunay->GetContainingTriangle(P, info); } inline size_t GetInvalidIndex() const { return mDelaunay->negOne; } bool GetVertices(size_t t, std::array, 3>& vertices) const { if (mDelaunay->GetDimension() == 2) { std::array indices = { 0, 0, 0 }; if (mDelaunay->GetIndices(t, indices)) { auto const& delaunayVertices = *mDelaunay->GetVertices(); for (size_t i = 0; i < 3; ++i) { vertices[i] = delaunayVertices[indices[i]]; } return true; } } return false; } bool GetIndices(size_t t, std::array& indices) const { return mDelaunay->GetIndices(t, indices); } bool GetAdjacencies(size_t t, std::array& adjacencies) const { return mDelaunay->GetAdjacencies(t, adjacencies); } bool GetBarycentrics(size_t t, Vector2 const& P, std::array& bary) const { std::array indices = { 0, 0, 0 }; if (mDelaunay->GetIndices(t, indices)) { auto const& delaunayVertices = *mDelaunay->GetVertices(); std::array, 3> rtV; for (size_t i = 0; i < 3; ++i) { auto const& V = delaunayVertices[indices[i]]; for (size_t j = 0; j < 2; ++j) { rtV[i][j] = static_cast(V[j]); } }; Vector2 rtP{ P[0], P[1] }; std::array rtBary; if (ComputeBarycentrics(rtP, rtV[0], rtV[1], rtV[2], rtBary.data())) { for (size_t i = 0; i < 3; ++i) { bary[i] = static_cast(rtBary[i]); } return true; } } return false; } private: using Rational = BSRational; Delaunay2 const* mDelaunay; }; }