TriangleMesh3.hpp
Go to the documentation of this file.
1 // This code is based on Jet framework.
2 // Copyright (c) 2018 Doyub Kim
3 // CubbyFlow is voxel-based fluid simulation engine for computer games.
4 // Copyright (c) 2020 CubbyFlow Team
5 // Core Part: Chris Ohk, Junwoo Hwang, Jihong Sin, Seungwoo Yoo
6 // AI Part: Dongheon Cho, Minseo Kim
7 // We are making my contributions/submissions to this project solely in our
8 // personal capacity and are not conveying any rights to any intellectual
9 // property of any third parties.
10 
11 #ifndef CUBBYFLOW_TRIANGLE_MESH3_HPP
12 #define CUBBYFLOW_TRIANGLE_MESH3_HPP
13 
14 #include <Core/Array/Array.hpp>
15 #include <Core/Geometry/BVH.hpp>
18 
19 namespace CubbyFlow
20 {
28 class TriangleMesh3 final : public Surface3
29 {
30  public:
31  class Builder;
32 
36 
40 
42  TriangleMesh3(const Transform3& _transform = Transform3{},
43  bool _isNormalFlipped = false);
44 
46  TriangleMesh3(PointArray points, NormalArray normals, UVArray uvs,
47  IndexArray pointIndices, IndexArray normalIndices,
48  IndexArray uvIndices,
49  const Transform3& _transform = Transform3{},
50  bool _isNormalFlipped = false);
51 
53  TriangleMesh3(const TriangleMesh3& other);
54 
56  TriangleMesh3(TriangleMesh3&& other) noexcept = delete;
57 
58  // Default virtual destructor.
59  ~TriangleMesh3() override = default;
60 
62  TriangleMesh3& operator=(const TriangleMesh3& other);
63 
65  TriangleMesh3& operator=(TriangleMesh3&& other) noexcept = delete;
66 
68  void UpdateQueryEngine() override;
69 
71  void UpdateQueryEngine() const;
72 
74  void Clear();
75 
77  void Set(const TriangleMesh3& other);
78 
80  void Swap(TriangleMesh3& other);
81 
83  [[nodiscard]] double Area() const;
84 
86  [[nodiscard]] double Volume() const;
87 
89  [[nodiscard]] const Vector3D& Point(size_t i) const;
90 
92  [[nodiscard]] Vector3D& Point(size_t i);
93 
95  [[nodiscard]] const Vector3D& Normal(size_t i) const;
96 
98  [[nodiscard]] Vector3D& Normal(size_t i);
99 
101  [[nodiscard]] const Vector2D& UV(size_t i) const;
102 
104  [[nodiscard]] Vector2D& UV(size_t i);
105 
107  [[nodiscard]] const Vector3UZ& PointIndex(size_t i) const;
108 
110  [[nodiscard]] Vector3UZ& PointIndex(size_t i);
111 
113  [[nodiscard]] const Vector3UZ& NormalIndex(size_t i) const;
114 
116  [[nodiscard]] Vector3UZ& NormalIndex(size_t i);
117 
119  [[nodiscard]] const Vector3UZ& UVIndex(size_t i) const;
120 
122  [[nodiscard]] Vector3UZ& UVIndex(size_t i);
123 
125  [[nodiscard]] Triangle3 Triangle(size_t i) const;
126 
128  [[nodiscard]] size_t NumberOfPoints() const;
129 
131  [[nodiscard]] size_t NumberOfNormals() const;
132 
134  [[nodiscard]] size_t NumberOfUVs() const;
135 
137  [[nodiscard]] size_t NumberOfTriangles() const;
138 
140  [[nodiscard]] bool HasNormals() const;
141 
143  [[nodiscard]] bool HasUVs() const;
144 
146  void AddPoint(const Vector3D& pt);
147 
149  void AddNormal(const Vector3D& n);
150 
152  void AddUV(const Vector2D& t);
153 
155  void AddPointTriangle(const Vector3UZ& newPointIndices);
156 
158  void AddNormalTriangle(const Vector3UZ& newNormalIndices);
159 
161  void AddUVTriangle(const Vector3UZ& newUVIndices);
162 
164  void AddTriangle(const Triangle3& tri);
165 
167  void SetFaceNormal();
168 
171 
173  void Scale(double factor);
174 
176  void Translate(const Vector3D& t);
177 
179  void Rotate(const QuaternionD& q);
180 
182  void WriteObj(std::ostream* stream) const;
183 
185  [[nodiscard]] bool WriteObj(const std::string& fileName) const;
186 
188  [[nodiscard]] bool ReadObj(std::istream* stream);
189 
191  [[nodiscard]] bool ReadObj(const std::string& fileName);
192 
194  [[nodiscard]] static Builder GetBuilder();
195 
196  protected:
197  [[nodiscard]] Vector3D ClosestPointLocal(
198  const Vector3D& otherPoint) const override;
199 
200  [[nodiscard]] double ClosestDistanceLocal(
201  const Vector3D& otherPoint) const override;
202 
203  [[nodiscard]] bool IntersectsLocal(const Ray3D& ray) const override;
204 
205  [[nodiscard]] BoundingBox3D BoundingBoxLocal() const override;
206 
207  [[nodiscard]] Vector3D ClosestNormalLocal(
208  const Vector3D& otherPoint) const override;
209 
211  const Ray3D& ray) const override;
212 
213  [[nodiscard]] bool IsInsideLocal(const Vector3D& otherPoint) const override;
214 
215  private:
216  void InvalidateCache() const;
217 
218  void InvalidateBVH() const;
219 
220  void BuildBVH() const;
221 
222  void BuildWindingNumbers() const;
223 
224  [[nodiscard]] double GetWindingNumber(const Vector3D& queryPoint,
225  size_t triIndex) const;
226 
227  [[nodiscard]] double GetFastWindingNumber(const Vector3D& queryPoint,
228  double accuracy) const;
229 
230  [[nodiscard]] double GetFastWindingNumber(const Vector3D& queryPoint,
231  size_t rootNodeIndex,
232  double accuracy) const;
233 
234  PointArray m_points;
235  NormalArray m_normals;
236  UVArray m_uvs;
237  IndexArray m_pointIndices;
238  IndexArray m_normalIndices;
239  IndexArray m_uvIndices;
240 
241  mutable BVH3<size_t> m_bvh;
242  mutable bool m_bvhInvalidated = true;
243 
244  mutable Array1<Vector3D> m_wnAreaWeightedNormalSums;
245  mutable Array1<Vector3D> m_wnAreaWeightedAvgPositions;
246  mutable bool m_wnInvalidated = true;
247 };
248 
250 using TriangleMesh3Ptr = std::shared_ptr<TriangleMesh3>;
251 
255 class TriangleMesh3::Builder final : public SurfaceBuilderBase3<Builder>
256 {
257  public:
259  [[nodiscard]] Builder& WithPoints(const PointArray& points);
260 
262  [[nodiscard]] Builder& WithNormals(const NormalArray& normals);
263 
265  [[nodiscard]] Builder& WithUVs(const UVArray& uvs);
266 
268  [[nodiscard]] Builder& WithPointIndices(const IndexArray& pointIndices);
269 
271  [[nodiscard]] Builder& WithNormalIndices(const IndexArray& normalIndices);
272 
274  [[nodiscard]] Builder& WithUVIndices(const IndexArray& uvIndices);
275 
277  [[nodiscard]] TriangleMesh3 Build() const;
278 
280  [[nodiscard]] TriangleMesh3Ptr MakeShared() const;
281 
282  private:
283  PointArray m_points;
284  NormalArray m_normals;
285  UVArray m_uvs;
286  IndexArray m_pointIndices;
287  IndexArray m_normalIndices;
288  IndexArray m_uvIndices;
289 };
290 } // namespace CubbyFlow
291 
292 #endif
double Volume() const
Returns volume of this mesh.
const Vector3UZ & NormalIndex(size_t i) const
Returns constant reference to the normal indices of i-th triangle.
void AddUVTriangle(const Vector3UZ &newUVIndices)
Adds a triangle with UV.
void AddNormalTriangle(const Vector3UZ &newNormalIndices)
Adds a triangle with normal.
void AddUV(const Vector2D &t)
Adds a UV.
const Vector3UZ & PointIndex(size_t i) const
Returns constant reference to the point indices of i-th triangle.
Class for N-D ray.
Definition: Ray.hpp:25
Vector3D ClosestPointLocal(const Vector3D &otherPoint) const override
TriangleMesh3(const Transform3 &_transform=Transform3{}, bool _isNormalFlipped=false)
Constructs an empty triangle mesh.
size_t NumberOfTriangles() const
Returns number of triangles.
double ClosestDistanceLocal(const Vector3D &otherPoint) const override
void AddTriangle(const Triangle3 &tri)
Add a triangle.
void AddPoint(const Vector3D &pt)
Adds a point.
N-D axis-aligned bounding box class.
Definition: BoundingBox.hpp:46
SurfaceRayIntersection3 ClosestIntersectionLocal(const Ray3D &ray) const override
double Area() const
Returns area of this mesh.
void Clear()
Clears all content.
size_t NumberOfUVs() const
Returns number of UV coordinates.
TriangleMesh3 & operator=(const TriangleMesh3 &other)
Deleted copy assignment operator.
BoundingBox3D BoundingBoxLocal() const override
Returns the bounding box of this surface object in local frame.
bool ReadObj(std::istream *stream)
Reads the mesh in obj format from the input stream.
const Vector2D & UV(size_t i) const
Returns constant reference to the i-th UV coordinates.
void SetFaceNormal()
Sets entire normals to the face normals.
Array1< Vector3D > Vector3DArray
Definition: TriangleMesh3.hpp:34
const Vector3D & Normal(size_t i) const
Returns constant reference to the i-th normal.
void WriteObj(std::ostream *stream) const
Writes the mesh in obj format to the output stream.
const Vector3UZ & UVIndex(size_t i) const
Returns constant reference to the UV indices of i-th triangle.
Front-end to create TriangleMesh3 objects step by step.
Definition: TriangleMesh3.hpp:255
void UpdateQueryEngine() override
Updates internal spatial query engine.
Represents N-D rigid body transform.
Definition: Transform.hpp:82
void Scale(double factor)
Scales the mesh by given factor.
Definition: Matrix.hpp:27
static Builder GetBuilder()
Returns builder fox TriangleMesh3.
Definition: pybind11Utils.hpp:20
std::shared_ptr< TriangleMesh3 > TriangleMesh3Ptr
Shared pointer for the TriangleMesh3 type.
Definition: TriangleMesh3.hpp:250
Array1< Vector2D > Vector2DArray
Definition: TriangleMesh3.hpp:33
Definition: Array-Impl.hpp:19
bool HasUVs() const
Returns true if the mesh has UV coordinates.
Abstract base class for N-D surface.
Definition: Surface.hpp:38
void AddNormal(const Vector3D &n)
Adds a normal.
Struct that represents ray-surface intersection point.
Definition: Surface.hpp:25
void Swap(TriangleMesh3 &other)
Swaps the contents with other mesh.
void AddPointTriangle(const Vector3UZ &newPointIndices)
Adds a triangle with point.
Vector3D ClosestNormalLocal(const Vector3D &otherPoint) const override
void Translate(const Vector3D &t)
Translates the mesh.
bool IsInsideLocal(const Vector3D &otherPoint) const override
const Vector3D & Point(size_t i) const
Returns constant reference to the i-th point.
~TriangleMesh3() override=default
3-D triangle geometry.
Definition: Triangle3.hpp:24
void SetAngleWeightedVertexNormal()
Sets angle weighted vertex normal.
size_t NumberOfNormals() const
Returns number of normals.
Triangle3 Triangle(size_t i) const
Returns i-th triangle.
size_t NumberOfPoints() const
Returns number of points.
Bounding Volume Hierarchy (BVH) in N-D.
Definition: BVH.hpp:30
void Set(const TriangleMesh3 &other)
Copies the contents from other mesh.
bool IntersectsLocal(const Ray3D &ray) const override
bool HasNormals() const
Returns true if the mesh has normals.
3-D triangle mesh geometry.
Definition: TriangleMesh3.hpp:28
void Rotate(const QuaternionD &q)
Rotates the mesh.
Base class for N-D surface builder.
Definition: Surface.hpp:153