Loading...
Searching...
No Matches
meshGeneratorBase.h
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
27#include "pxr/imaging/geomUtil/api.h"
28
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
38PXR_NAMESPACE_OPEN_SCOPE
39
41
78{
79private:
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.
84
85protected:
86
87 // SFINAE helper types, for more compact and readable template shenanigans
88 // in the subclasses.
89 template<typename IterType>
90 struct _IsGfVec3Iterator
91 {
92 using PointType = typename std::iterator_traits<IterType>::value_type;
93 static constexpr bool value =
94 std::is_same<PointType, GfVec3f>::value ||
95 std::is_same<PointType, GfVec3d>::value;
96 };
97
98 template<typename IterType>
99 struct _EnableIfGfVec3Iterator
100 : public std::enable_if<_IsGfVec3Iterator<IterType>::value, void>
101 {};
102
103 template<typename IterType>
104 struct _EnableIfNotGfVec3Iterator
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>
122 struct _PointWriter
123 {
124 template<class IterType>
125 _PointWriter(
126 IterType& iter)
127 : _writeFnPtr(&_PointWriter<PointType>::_WritePoint<IterType>)
128 , _untypedIterPtr(static_cast<void*>(&iter))
129 {}
130
131 template<class IterType>
132 _PointWriter(
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 {
201 CapStyleNone,
202 CapStyleSharedEdge,
203 CapStyleSeparateEdge
204 };
205
206 static PxOsdMeshTopology _GenerateCappedQuadTopology(
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
222public:
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 =
233 typename _EnableIfNotGfVec3Iterator<PointIterType>::type>
234 static void GeneratePoints(
235 PointIterType iter, ...)
236 {
237 static_assert(_IsGfVec3Iterator<PointIterType>::value,
238 "This function only supports iterators to GfVec3f or GfVec3d "
239 "objects.");
240 }
241
242};
243
244
245PXR_NAMESPACE_CLOSE_SCOPE
246
247#endif // PXR_IMAGING_GEOM_UTIL_MESH_GENERATOR_BASE_H
This class provides common implementation for the different mesh generator classes in GeomUtil.
Stores a 4x4 matrix of double elements.
Definition: matrix4d.h:88
Topology data for meshes.
Definition: meshTopology.h:69