GtePolyhedron3.h
Go to the documentation of this file.
1 // David Eberly, Geometric Tools, Redmond WA 98052
2 // Copyright (c) 1998-2017
3 // Distributed under the Boost Software License, Version 1.0.
4 // http://www.boost.org/LICENSE_1_0.txt
5 // http://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
6 // File Version: 3.0.0 (2016/06/19)
7 
8 #pragma once
9 
10 #include <Mathematics/GteVector3.h>
11 #include <algorithm>
12 #include <memory>
13 #include <set>
14 #include <vector>
15 
16 // The Polyhedron3 object represents a simple polyhedron. The 'vertexPool'
17 // array can contain more points than needed to define the polyhedron, which
18 // allows the vertex pool to have multiple polyhedra associated with it.
19 // Thus, the programmer must ensure that the vertex pool persists as long as
20 // any Polyhedron3 objects exist that depend on the pool. The number of
21 // polyhedron indices is 'numIndices' and must be 6 or larger The 'indices'
22 // array refers to the points in 'vertexPool' that form the triangle faces,
23 // so 'numIndices' must be a multiple of 3. The number of vertices is
24 // the number of unique elements in 'indices' and is determined during
25 // construction. The programmer should ensure the polyhedron is simple. The
26 // geometric queries are valid regardless of whether the polyhedron triangles
27 // are oriented clockwise or counterclockwise.
28 //
29 // NOTE: Comparison operators are not provided. The semantics of equal
30 // polyhedra is complicated and (at the moment) not useful. The vertex pools
31 // can be different and indices do not match, but the vertices they reference
32 // can match. Even with a shared vertex pool, the indices can be permuted,
33 // leading to the same polyhedron abstractly but the data structures do not
34 // match.
35 
36 namespace gte
37 {
38 
39 template <typename Real>
41 {
42 public:
43  // Construction. The constructor succeeds when 'numIndices >= 12' (at
44  // least 4 triangles), and 'vertexPool' and 'indices' are not null; we
45  // cannot test whether you have a valid number of elements in the input
46  // arrays. A copy is made of 'indices', but the 'vertexPool' is not
47  // copied. If the constructor fails, the internal vertex pointer is set
48  // to null, the number of vertices is set to zero, the index array has no
49  // elements, and the triangle face orientation is set to clockwise.
50  Polyhedron3(std::shared_ptr<std::vector<Vector3<Real>>> const& vertexPool,
51  int numIndices, int const* indices, bool counterClockwise);
52 
53  // To validate construction, create an object as shown:
54  // Polyhedron3<Real> polyhedron(parameters);
55  // if (!polyhedron) { <constructor failed, handle accordingly>; }
56  inline operator bool() const;
57 
58  // Member access.
59  inline std::shared_ptr<std::vector<Vector3<Real>>> const& GetVertexPool() const;
60  inline std::vector<Vector3<Real>> const& GetVertices() const;
61  inline std::set<int> const& GetUniqueIndices() const;
62  inline std::vector<int> const& GetIndices() const;
63  inline bool CounterClockwise() const;
64 
65  // Geometric queries.
67  Real ComputeSurfaceArea() const;
68  Real ComputeVolume() const;
69 
70 private:
71  std::shared_ptr<std::vector<Vector3<Real>>> mVertexPool;
72  std::set<int> mUniqueIndices;
73  std::vector<int> mIndices;
75 };
76 
77 
78 template <typename Real>
79 Polyhedron3<Real>::Polyhedron3(std::shared_ptr<std::vector<Vector3<Real>>> const& vertexPool,
80  int numIndices, int const* indices, bool counterClockwise)
81  :
82  mVertexPool(vertexPool),
83  mCounterClockwise(counterClockwise)
84 {
85  if (vertexPool && indices && numIndices >= 12 && (numIndices % 3) == 0)
86  {
87  for (int i = 0; i < numIndices; ++i)
88  {
89  mUniqueIndices.insert(indices[i]);
90  }
91 
92  mIndices.resize(numIndices);
93  std::copy(indices, indices + numIndices, mIndices.begin());
94  }
95  else
96  {
97  // Encountered an invalid input.
98  mVertexPool = nullptr;
99  mCounterClockwise = false;
100  }
101 }
102 
103 template <typename Real> inline
105 {
106  return mVertexPool != nullptr;
107 }
108 
109 template <typename Real> inline
110 std::shared_ptr<std::vector<Vector3<Real>>> const& Polyhedron3<Real>::GetVertexPool() const
111 {
112  return mVertexPool;
113 }
114 
115 template <typename Real> inline
116 std::vector<Vector3<Real>> const& Polyhedron3<Real>::GetVertices() const
117 {
118  return *mVertexPool.get();
119 }
120 
121 template <typename Real> inline
122 std::set<int> const& Polyhedron3<Real>::GetUniqueIndices() const
123 {
124  return mUniqueIndices;
125 }
126 
127 template <typename Real> inline
128 std::vector<int> const& Polyhedron3<Real>::GetIndices() const
129 {
130  return mIndices;
131 }
132 
133 template <typename Real> inline
135 {
136  return mCounterClockwise;
137 }
138 
139 template <typename Real>
141 {
143  if (mVertexPool)
144  {
145  auto vertexPool = GetVertices();
146  for (int index : mUniqueIndices)
147  {
148  average += vertexPool[index];
149  }
150  average /= static_cast<Real>(mUniqueIndices.size());
151  }
152  return average;
153 }
154 
155 template <typename Real>
157 {
158  Real surfaceArea = (Real)0;
159  if (mVertexPool)
160  {
161  auto vertexPool = GetVertices();
162  int const numTriangles = static_cast<int>(mIndices.size()) / 3;
163  int const* indices = mIndices.data();
164  for (int t = 0; t < numTriangles; ++t)
165  {
166  int v0 = *indices++;
167  int v1 = *indices++;
168  int v2 = *indices++;
169  Vector3<Real> edge0 = vertexPool[v1] - vertexPool[v0];
170  Vector3<Real> edge1 = vertexPool[v2] - vertexPool[v0];
171  Vector3<Real> cross = Cross(edge0, edge1);
172  surfaceArea += Length(cross);
173  }
174  surfaceArea *= (Real)0.5;
175  }
176  return surfaceArea;
177 }
178 
179 template <typename Real>
181 {
182  Real volume = (Real)0;
183  if (mVertexPool)
184  {
185  auto vertexPool = GetVertices();
186  int const numTriangles = static_cast<int>(mIndices.size()) / 3;
187  int const* indices = mIndices.data();
188  for (int t = 0; t < numTriangles; ++t)
189  {
190  int v0 = *indices++;
191  int v1 = *indices++;
192  int v2 = *indices++;
193  volume += DotCross(vertexPool[v0], vertexPool[v1], vertexPool[v2]);
194  }
195  volume /= (Real)6;
196  }
197  return fabs(volume);
198 }
199 
200 }
std::vector< Vector3< Real > > const & GetVertices() const
std::vector< int > const & GetIndices() const
Polyhedron3(std::shared_ptr< std::vector< Vector3< Real >>> const &vertexPool, int numIndices, int const *indices, bool counterClockwise)
GLfloat GLfloat v1
Definition: glcorearb.h:812
bool CounterClockwise() const
std::set< int > mUniqueIndices
Real ComputeSurfaceArea() const
Real ComputeVolume() const
GLsizei GLenum const void * indices
Definition: glcorearb.h:401
Vector3< Real > ComputeVertexAverage() const
static Vector Zero()
Definition: GteVector.h:295
GLfloat v0
Definition: glcorearb.h:811
GLdouble GLdouble t
Definition: glext.h:239
std::set< int > const & GetUniqueIndices() const
DualQuaternion< Real > Cross(DualQuaternion< Real > const &d0, DualQuaternion< Real > const &d1)
Real DotCross(Vector< N, Real > const &v0, Vector< N, Real > const &v1, Vector< N, Real > const &v2)
Definition: GteVector3.h:140
std::shared_ptr< std::vector< Vector3< Real > > > mVertexPool
DualQuaternion< Real > Length(DualQuaternion< Real > const &d, bool robust=false)
GLfloat GLfloat GLfloat v2
Definition: glcorearb.h:813
GLuint index
Definition: glcorearb.h:781
std::shared_ptr< std::vector< Vector3< Real > > > const & GetVertexPool() const
std::vector< int > mIndices


geometric_tools_engine
Author(s): Yijiang Huang
autogenerated on Thu Jul 18 2019 04:00:01