HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
meshGeneratorBase.h
Go to the documentation of this file.
1 //
2 // Copyright 2022 Pixar
3 //
4 // Licensed under the Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 // names, trademarks, service marks, or product names of the Licensor
11 // and its affiliates, except as required to comply with Section 4(c) of
12 // the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 // http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 #ifndef PXR_IMAGING_GEOM_UTIL_MESH_GENERATOR_BASE_H
25 #define PXR_IMAGING_GEOM_UTIL_MESH_GENERATOR_BASE_H
26 
28 
29 #include "pxr/base/gf/matrix4d.h"
30 #include "pxr/base/gf/vec3d.h"
31 #include "pxr/base/gf/vec3f.h"
32 
33 #include "pxr/pxr.h"
34 
35 #include <iterator>
36 #include <type_traits>
37 
39 
40 class PxOsdMeshTopology;
41 
42 /// This class provides common implementation for the different mesh generator
43 /// classes in GeomUtil. As the mesh generators are entirely implemented as
44 /// static functions, this "base class" is more of a grouping and access control
45 /// mechanism than a base class in the polymorphic sense.
46 ///
47 /// The mesh generator subclasses all follow a common pattern, providing static
48 /// methods for generating topology and point positions for their specific
49 /// geometric primitive. The data produced by these classes is only guaranteed
50 /// to be suitable for imaging the described surface; it is only one of many
51 /// possible interpretations of the surface, and should not be relied upon for
52 /// any other use. The generators may e.g. change the topology or ordering of
53 /// the produced data at any time. In short: these utilities are meant only to
54 /// be used to produce a blob of semi-blind data, for feeding to an imager that
55 /// supports PxOsdMeshTopology.
56 ///
57 /// The generators make use of templates and SFINAE to allow clients to pass any
58 /// output iterator that dereferences to either a GfVec3f or GfVec3d to their
59 /// GeneratePoints(...) method, and internally perform compile-time type erasure
60 /// in order to allow the implementations of their algorithms to be private
61 /// implementation detail, not defined in the headers. Although it's expected
62 /// that clients will typically want their point data in VtVec3fArray, the
63 /// described implementation was chosen to minimize the chance that any
64 /// prospective client with unusual data management requirements would be unable
65 /// to make use of the generators, or would be forced to resort to a container
66 /// copy in order to do so.
67 ///
68 /// The only public API on this class is a static GeneratePoints(...) template
69 /// method, intended to be added by subclasses to their GeneratePoints(...)
70 /// overload sets. It serves as the "error case" for callers that attempt to
71 /// pass iterators of unsupported types to the GeneratePoints(...) methods each
72 /// subclass declares. As all generator subclasses have this possibility and
73 /// the implementation requires SFINAE, it's implemented here and shared between
74 /// all subclasses. However, it's important that subclasses explicitly include
75 /// a "using" statement for the fallback to be included in overload resolution.
76 ///
78 {
79 private:
80 
81  // Delete the implicit default c'tor. This class and its subclasses are
82  // only for grouping; there's never any need to make instances.
83  GeomUtilMeshGeneratorBase() = delete;
84 
85 protected:
86 
87  // SFINAE helper types, for more compact and readable template shenanigans
88  // in the subclasses.
89  template<typename IterType>
91  {
93  static constexpr bool value =
96  };
97 
98  template<typename IterType>
100  : public std::enable_if<_IsGfVec3Iterator<IterType>::value, void>
101  {};
102 
103  template<typename IterType>
105  : public std::enable_if<!_IsGfVec3Iterator<IterType>::value, void>
106  {};
107 
108  // Helper struct to provide iterator type erasure, allowing subclasses to
109  // implement their GeneratePoints methods privately. Usage doesn't require
110  // any heap allocation or virtual dispatch/runtime typing. In addition to
111  // erasing the iterator type, this also provides a convenient way to allow
112  // subclasses to offer GeneratePoints methods that can apply an additional
113  // frame transform without having to actually plumb that detail into the
114  // guts of their point generator code.
115  //
116  // Note: Ensuring the interoperability of the PointType with the IterType
117  // used at construction is the responsibility of the client. It's typically
118  // guaranteed by the client deriving PointType from IterType; see subclass
119  // use for examples and how they guarantee IterType dereferences to a
120  // supportable point type.
121  template<typename PointType>
123  {
124  template<class IterType>
126  IterType& iter)
127  : _writeFnPtr(&_PointWriter<PointType>::_WritePoint<IterType>)
128  , _untypedIterPtr(static_cast<void*>(&iter))
129  {}
130 
131  template<class IterType>
133  IterType& iter,
134  const GfMatrix4d* const framePtr)
135  : _writeFnPtr(
136  &_PointWriter<PointType>::_TransformAndWritePoint<IterType>)
137  , _untypedIterPtr(static_cast<void*>(&iter))
138  , _framePtr(framePtr)
139  {}
140 
141  void Write(
142  const PointType& pt) const
143  {
144  (this->*_writeFnPtr)(pt);
145  }
146 
147  private:
148  template<class IterType>
149  void _WritePoint(
150  const PointType& pt) const
151  {
152  IterType& iter = *static_cast<IterType*>(_untypedIterPtr);
153  *iter = pt;
154  ++iter;
155  }
156 
157  template<class IterType>
158  void _TransformAndWritePoint(
159  const PointType& pt) const
160  {
161  IterType& iter = *static_cast<IterType*>(_untypedIterPtr);
162  *iter = _framePtr->Transform(pt);
163  ++iter;
164  }
165 
166  using _WriteFnPtr =
167  void (_PointWriter<PointType>::*)(const PointType &) const;
168  _WriteFnPtr _writeFnPtr;
169  void* _untypedIterPtr;
170  const GfMatrix4d* _framePtr;
171  };
172 
173  // Common topology helper method.
174  //
175  // Several of the subclasses make use of a common topology, specifically "a
176  // triangle fan around a 'bottom' point, some number of quad strips forming
177  // rings with shared edges, and another triangle fan surrounding a 'top'
178  // point." The two triangle fans can be considered "caps" on a "tube" of
179  // linked quad strips. This triangle fans + quad strips topology also
180  // describes the latitude/longitude topology of the globe, as another
181  // example.
182  //
183  // Because we currently rely on downstream machinery to infer surface
184  // normals from the topology, we sometimes want the "caps" to share their
185  // edge-ring with the adjacent quad strip, and other times need that edge-
186  // ring to not be shared between the "cap" and "body" surfaces. The edges
187  // are coincident in space but the surface is not continuous across that
188  // edge.
189  //
190  // Subclasses specify the "cap" conditions they require to support the
191  // surface-continuity condition described above, and other uses where a
192  // "cap" is not needed (e.g. the point-end of a cone).
193  //
194  // Subclasses also specify whether the surface is closed or open. This
195  // is typically exposed via a sweep parameter, wherein a sweep of a multiple
196  // of 2 * pi results in a "closed" surface. The generated points and by
197  // extension, the generated topology, differs for "open" and "closed"
198  // surfaces.
199  //
200  enum _CapStyle {
204  };
205 
207  const size_t numRadial,
208  const size_t numQuadStrips,
209  const _CapStyle bottomCapStyle,
210  const _CapStyle topCapStyle,
211  const bool closedSweep);
212 
213 
214  // Subclasses that use the topology helper method above generate one or more
215  // circular arcs during point generation. The number of radial points on
216  // each arc depends on the number of radial segments and whether the arc
217  // is fully swept (i.e., a ring).
218  static size_t _ComputeNumRadialPoints(
219  const size_t numRadial,
220  const bool closedSweep);
221 
222 public:
223 
224  // This template provides a "fallback" for GeneratePoints(...) calls that
225  // do not meet the SFINAE requirement that the given point-container-
226  // iterator must dereference to a GfVec3f or GfVec3d. This version
227  // generates a helpful compile time assertion in such a scenario. As noted
228  // earlier, subclasses should explicitly add a "using" statement with
229  // this method to include it in overload resolution.
230  //
231  template<typename PointIterType,
232  typename Enabled =
234  static void GeneratePoints(
235  PointIterType iter, ...)
236  {
238  "This function only supports iterators to GfVec3f or GfVec3d "
239  "objects.");
240  }
241 
242 };
243 
244 
246 
247 #endif // PXR_IMAGING_GEOM_UTIL_MESH_GENERATOR_BASE_H
void
Definition: png.h:1083
GLsizei const GLfloat * value
Definition: glcorearb.h:824
GfVec3d Transform(const GfVec3d &vec) const
Definition: matrix4d.h:669
uint64 value_type
Definition: GA_PrimCompat.h:29
_PointWriter(IterType &iter, const GfMatrix4d *const framePtr)
void Write(const PointType &pt) const
typename std::iterator_traits< IterType >::value_type PointType
static PxOsdMeshTopology _GenerateCappedQuadTopology(const size_t numRadial, const size_t numQuadStrips, const _CapStyle bottomCapStyle, const _CapStyle topCapStyle, const bool closedSweep)
static void GeneratePoints(PointIterType iter,...)
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1441
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:91
static size_t _ComputeNumRadialPoints(const size_t numRadial, const bool closedSweep)
Definition: core.h:1131
type
Definition: core.h:1059