GteTubeMesh.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.5 (2016/08/29)
7 
8 #pragma once
9 
10 #include <Mathematics/GteMesh.h>
13 #include <functional>
14 #include <memory>
15 
16 namespace gte
17 {
18 
19 template <typename Real>
20 class TubeMesh : public Mesh<Real>
21 {
22 public:
23  // Create a mesh (x(u,v),y(u,v),z(u,v)) defined by the specified medial
24  // curve and radial function. The mesh has torus topology when 'closed'
25  // is true and has cylinder topology when 'closed' is false. The client
26  // is responsible for setting the topology correctly in the 'description'
27  // input. The rows correspond to medial samples and the columns
28  // correspond to radial samples. The medial curve is sampled according
29  // to its natural t-parameter when 'sampleByArcLength' is false;
30  // otherwise, it is sampled uniformly in arclength.
31  TubeMesh(MeshDescription const& description,
32  std::shared_ptr<ParametricCurve<3, Real>> const& medial,
33  std::function<Real(Real)> const& radial, bool closed,
34  bool sampleByArcLength, Vector3<Real> upVector);
35 
36  // Member access.
37  inline std::shared_ptr<ParametricCurve<3, Real>> const& GetMedial() const;
38  inline std::function<Real(Real)> const& GetRadial() const;
39  inline bool IsClosed() const;
40  inline bool IsSampleByArcLength() const;
41  inline Vector3<Real> const& GetUpVector() const;
42 
43 private:
44  void InitializeTCoords();
45  virtual void UpdatePositions() override;
46 
47  std::shared_ptr<ParametricCurve<3, Real>> mMedial;
48  std::function<Real(Real)> mRadial;
51  std::vector<Real> mCosAngle, mSinAngle;
52  std::function<Real(unsigned int)> mTSampler;
53  std::function<std::array<Vector3<Real>, 4>(Real)> mFSampler;
54  std::unique_ptr<FrenetFrame3<Real>> mFrenet;
55 
56  // If the client does not request texture coordinates, they will be
57  // computed internally for use in evaluation of the surface geometry.
58  std::vector<Vector2<Real>> mDefaultTCoords;
59 };
60 
61 
62 template <typename Real>
64  std::shared_ptr<ParametricCurve<3, Real>> const& medial,
65  std::function<Real(Real)> const& radial, bool closed, bool sampleByArcLength,
66  Vector3<Real> upVector)
67  :
68  Mesh<Real>(description, { MeshTopology::CYLINDER }), // TODO: Allow TORUS and remove the 'closed' input
69  mMedial(medial),
70  mRadial(radial),
71  mClosed(closed),
72  mSampleByArcLength(sampleByArcLength),
73  mUpVector(upVector)
74 {
75  if (!this->mDescription.constructed)
76  {
77  // The logger system will report these errors in the Mesh constructor.
78  mMedial = nullptr;
79  return;
80  }
81 
82  if (!mMedial)
83  {
84  LogWarning("A nonnull medial curve is required.");
85  this->mDescription.constructed = false;
86  return;
87  }
88 
89  mCosAngle.resize(this->mDescription.numCols);
90  mSinAngle.resize(this->mDescription.numCols);
91  Real invRadialSamples = (Real)1 / (Real)(this->mDescription.numCols - 1);
92  for (unsigned int i = 0; i < this->mDescription.numCols - 1; ++i)
93  {
94  Real angle = i * invRadialSamples * (Real)GTE_C_TWO_PI;
95  mCosAngle[i] = cos(angle);
96  mSinAngle[i] = sin(angle);
97  }
98  mCosAngle[this->mDescription.numCols - 1] = mCosAngle[0];
99  mSinAngle[this->mDescription.numCols - 1] = mSinAngle[0];
100 
101  Real invDenom;
102  if (mClosed)
103  {
104  invDenom = ((Real)1) / (Real)this->mDescription.numRows;
105  }
106  else
107  {
108  invDenom = ((Real)1) / (Real)(this->mDescription.numRows - 1);
109  }
110 
111  Real factor;
112  if (mSampleByArcLength)
113  {
114  factor = mMedial->GetTotalLength() * invDenom;
115  mTSampler = [this, factor](unsigned int row)
116  {
117  return mMedial->GetTime(row * factor);
118  };
119  }
120  else
121  {
122  factor = (mMedial->GetTMax() - mMedial->GetTMin()) * invDenom;
123  mTSampler = [this, factor](unsigned int row)
124  {
125  return mMedial->GetTMin() + row * factor;
126  };
127  }
128 
130  {
131  mFSampler = [this](Real t)
132  {
133  std::array<Vector3<Real>, 4> frame;
134  frame[0] = mMedial->GetPosition(t);
135  frame[1] = mMedial->GetTangent(t);
136  frame[3] = UnitCross(frame[1], mUpVector);
137  frame[2] = UnitCross(frame[3], frame[1]);
138  return frame;
139  };
140  }
141  else
142  {
143  mFrenet = std::make_unique<FrenetFrame3<Real>>(mMedial);
144  mFSampler = [this](Real t)
145  {
146  std::array<Vector3<Real>, 4> frame;
147  (*mFrenet)(t, frame[0], frame[1], frame[2], frame[3]);
148  return frame;
149  };
150  }
151 
152  if (!this->mTCoords)
153  {
155  this->mTCoords = mDefaultTCoords.data();
156  this->mTCoordStride = sizeof(Vector2<Real>);
157 
159  if (this->mDescription.allowUpdateFrame)
160  {
162  {
163  this->mDescription.allowUpdateFrame = false;
164  }
165 
166  if (!this->mNormals)
167  {
168  this->mDescription.allowUpdateFrame = false;
169  }
170  }
171  }
172 
173  this->ComputeIndices();
175  UpdatePositions();
176  if (this->mDescription.allowUpdateFrame)
177  {
178  this->UpdateFrame();
179  }
180  else if (this->mNormals)
181  {
182  this->UpdateNormals();
183  }
184 }
185 
186 template <typename Real>
187 inline std::shared_ptr<ParametricCurve<3, Real>> const& TubeMesh<Real>::GetMedial() const
188 {
189  return mMedial;
190 }
191 
192 template <typename Real>
193 inline std::function<Real(Real)> const& TubeMesh<Real>::GetRadial() const
194 {
195  return mRadial;
196 }
197 
198 template <typename Real>
199 inline bool TubeMesh<Real>::IsClosed() const
200 {
201  return mClosed;
202 }
203 
204 template <typename Real>
206 {
207  return mSampleByArcLength;
208 }
209 
210 template <typename Real>
212 {
213  return mUpVector;
214 }
215 
216 template <typename Real>
218 {
219  Vector2<Real>tcoord;
220  for (unsigned int r = 0, i = 0; r < this->mDescription.numRows; ++r)
221  {
222  tcoord[1] = (Real)r / (Real)this->mDescription.rMax;
223  for (unsigned int c = 0; c <= this->mDescription.numCols; ++c, ++i)
224  {
225  tcoord[0] = (Real)c / (Real)this->mDescription.numCols;
226  this->TCoord(i) = tcoord;
227  }
228  }
229 }
230 
231 template <typename Real>
233 {
234  uint32_t row, col, v, save;
235  for (row = 0, v = 0; row < this->mDescription.numRows; ++row, ++v)
236  {
237  Real t = mTSampler(row);
238  Real radius = mRadial(t);
239  // frame = (position, tangent, normal, binormal)
240  std::array<Vector3<Real>, 4> frame = mFSampler(t);
241  for (col = 0, save = v; col < this->mDescription.numCols; ++col, ++v)
242  {
243  this->Position(v) = frame[0] + radius * (mCosAngle[col] * frame[2] +
244  mSinAngle[col] * frame[3]);
245  }
246  this->Position(v) = this->Position(save);
247  }
248 
249  if (mClosed)
250  {
251  for (col = 0; col < this->mDescription.numCols; ++col)
252  {
253  uint32_t i0 = col;
254  uint32_t i1 = col + this->mDescription.numCols * (this->mDescription.numRows - 1);
255  this->Position(i1) = this->Position(i0);
256  }
257  }
258 }
259 
260 }
std::shared_ptr< ParametricCurve< 3, Real > > mMedial
Definition: GteTubeMesh.h:47
MeshDescription mDescription
Definition: GteMesh.h:163
std::vector< Vector2< Real > > mDefaultTCoords
Definition: GteTubeMesh.h:58
std::vector< Real > mCosAngle
Definition: GteTubeMesh.h:51
uint32_t numRows
Definition: GteMesh.h:97
Vector3< Real > mUpVector
Definition: GteTubeMesh.h:50
GLfloat angle
Definition: glext.h:6466
virtual void UpdateNormals()
Definition: GteMesh.h:586
Vector< N, Real > UnitCross(Vector< N, Real > const &v0, Vector< N, Real > const &v1, bool robust=false)
Definition: GteVector3.h:130
std::shared_ptr< ParametricCurve< 3, Real > > const & GetMedial() const
Definition: GteTubeMesh.h:187
bool mSampleByArcLength
Definition: GteTubeMesh.h:49
const GLubyte * c
Definition: glext.h:11671
GLenum GLenum GLsizei void * row
Definition: glext.h:2725
bool wantDynamicTangentSpaceUpdate
Definition: GteMesh.h:91
std::unique_ptr< FrenetFrame3< Real > > mFrenet
Definition: GteTubeMesh.h:54
Vector3< Real > * mNormals
Definition: GteMesh.h:167
std::function< Real(unsigned int)> mTSampler
Definition: GteTubeMesh.h:52
#define LogWarning(message)
Definition: GteLogger.h:95
GLdouble GLdouble t
Definition: glext.h:239
uint32_t numVertices
Definition: GteMesh.h:87
bool IsClosed() const
Definition: GteTubeMesh.h:199
virtual void UpdateFrame()
Definition: GteMesh.h:630
virtual void UpdatePositions() override
Definition: GteTubeMesh.h:232
std::vector< Real > mSinAngle
Definition: GteTubeMesh.h:51
Vector2< Real > & TCoord(uint32_t i)
Definition: GteMesh.h:508
const GLdouble * v
Definition: glcorearb.h:832
GLboolean r
Definition: glcorearb.h:1217
size_t mTCoordStride
Definition: GteMesh.h:179
Vector2< Real > * mTCoords
Definition: GteMesh.h:172
void ComputeIndices()
Definition: GteMesh.h:515
uint32_t numCols
Definition: GteMesh.h:97
bool hasTangentSpaceVectors
Definition: GteMesh.h:95
std::function< std::array< Vector3< Real >, 4 >Real)> mFSampler
Definition: GteTubeMesh.h:53
Vector3< Real > & Position(uint32_t i)
Definition: GteMesh.h:466
TubeMesh(MeshDescription const &description, std::shared_ptr< ParametricCurve< 3, Real >> const &medial, std::function< Real(Real)> const &radial, bool closed, bool sampleByArcLength, Vector3< Real > upVector)
Definition: GteTubeMesh.h:63
std::function< Real(Real)> const & GetRadial() const
Definition: GteTubeMesh.h:193
bool IsSampleByArcLength() const
Definition: GteTubeMesh.h:205
#define GTE_C_TWO_PI
Definition: GteConstants.h:20
std::function< Real(Real)> mRadial
Definition: GteTubeMesh.h:48
Vector3< Real > const & GetUpVector() const
Definition: GteTubeMesh.h:211
void InitializeTCoords()
Definition: GteTubeMesh.h:217


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