meshUtil.h
1 //
2 // Copyright 2017 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_HD_MESH_UTIL_H
25 #define PXR_IMAGING_HD_MESH_UTIL_H
26 
27 #include "pxr/pxr.h"
28 #include "pxr/imaging/hd/api.h"
29 #include "pxr/imaging/hd/version.h"
30 #include "pxr/imaging/hd/types.h"
31 #include "pxr/imaging/hd/meshTopology.h"
32 
33 #include "pxr/usd/sdf/path.h"
34 
35 #include "pxr/base/gf/vec2i.h"
36 #include "pxr/base/gf/vec3i.h"
37 #include "pxr/base/gf/vec4i.h"
38 
39 #include "pxr/base/vt/array.h"
40 #include "pxr/base/vt/value.h"
41 
42 PXR_NAMESPACE_OPEN_SCOPE
43 
46 
47 // v0 v2
48 // +-----e2----+
49 // \ | /
50 // \ __c__ /
51 // e0 e1
52 // \ /
53 // \ /
54 // + v1
55 //
56 //
57 // original points additional center and edge points
58 // +------------ ... ----+--------------------------------+
59 // | v0 v1 v2 vn | e0 e1 e2 c0, e3 e4 e5 c1 ... |
60 // +------------ ... ----+--------------------------------+
61 // ^
62 // pointsOffset
63 // <----- numAdditionalPoints ---->
64 
65 struct HdQuadInfo {
66  HdQuadInfo() : pointsOffset(0), numAdditionalPoints(0), maxNumVert(0) { }
67 
69  bool IsAllQuads() const { return numAdditionalPoints == 0; }
70 
71  int pointsOffset;
72  int numAdditionalPoints;
73  int maxNumVert;
74  std::vector<int> numVerts; // num vertices of non-quads
75  std::vector<int> verts; // vertex indices of non-quads
76 };
77 
81 
83 {
84 public:
85  HdMeshUtil(HdMeshTopology const* topology, SdfPath const& id)
86  : _topology(topology), _id(id) {}
87  virtual ~HdMeshUtil() {}
88 
89  // --------------------------------------------------------------------
101  /*
102  +--------+-------+
103  /| \ |\ |\
104  / | \ 1 | \ 2 | \
105  / | \ | \ | \
106  / | \ | \ | 2 +
107  / 0 | 1 \ | 2 \ | /
108  / | \ | \ | /
109  / | \| \|/
110  +-------+--------+-------+
111  */
112 
115  HD_API
116  void ComputeTriangleIndices(VtVec3iArray *indices,
117  VtIntArray *primitiveParams,
118  VtIntArray *edgeIndices = nullptr) const;
119 
125  HD_API
126  bool ComputeTriangulatedFaceVaryingPrimvar(void const* source,
127  int numElements,
128  HdType dataType,
129  VtValue *triangulated) const;
130 
132 
133  // --------------------------------------------------------------------
148 
149  /*
150  +--------+-------+
151  /| | | \
152  / | | 2 | 2 /\
153  / | | \ / \
154  / 0 | 1 |------+ 2 +
155  /\ /| | / \ /
156  / \/ | | 2 | 2 \/
157  / 0 | 0| | | /
158  +-------+--------+-------+
159  */
160 
162  HD_API
163  void ComputeQuadInfo(HdQuadInfo* quadInfo) const;
164 
167  HD_API
168  void ComputeQuadIndices(VtIntArray *indices,
169  VtIntArray *primitiveParams,
170  VtVec2iArray *edgeIndices = nullptr) const;
171 
174  HD_API
175  void ComputeTriQuadIndices(VtIntArray *indices,
176  VtIntArray *primitiveParams,
177  VtVec2iArray *edgeIndices = nullptr) const;
178 
184  HD_API
186  void const* source,
187  int numElements,
188  HdType dataType,
189  VtValue *quadrangulated) const;
190 
196  HD_API
197  bool ComputeQuadrangulatedFaceVaryingPrimvar(void const* source,
198  int numElements,
199  HdType dataType,
200  VtValue *quadrangulated) const;
201 
203 
211  HD_API
212  void EnumerateEdges(std::vector<GfVec2i> * edgeVerticesOut) const;
213 
214  // --------------------------------------------------------------------
234 
235  // Per-primitive coarse-face-param encoding/decoding functions
236  static int EncodeCoarseFaceParam(int faceIndex, int edgeFlag) {
237  return ((faceIndex << 2) | (edgeFlag & 3));
238  }
239  static int DecodeFaceIndexFromCoarseFaceParam(int coarseFaceParam) {
240  return (coarseFaceParam >> 2);
241  }
242  static int DecodeEdgeFlagFromCoarseFaceParam(int coarseFaceParam) {
243  return (coarseFaceParam & 3);
244  }
245 
247 
248 private:
251  int _ComputeNumQuads(VtIntArray const &numVerts,
252  VtIntArray const &holeIndices,
253  bool *invalidFaceFound = nullptr) const;
254 
256  void _ComputeQuadIndices(
257  VtIntArray *indices,
258  VtIntArray *primitiveParams,
259  VtVec2iArray *edgeIndices,
260  bool triangulate = false) const;
261 
262  HdMeshTopology const* _topology;
263  SdfPath const _id;
264 };
265 
313 {
314 public:
315  explicit HdMeshEdgeIndexTable(HdMeshTopology const * topology);
317 
318  bool GetVerticesForEdgeIndex(int edgeId, GfVec2i * edgeVerticesOut) const;
319 
320  bool GetVerticesForEdgeIndices(
321  std::vector<int> const & edgeIndices,
322  std::vector<GfVec2i> * edgeVerticesOut) const;
323 
324  bool GetEdgeIndices(GfVec2i const & edgeVertices,
325  std::vector<int> * edgeIndicesOut) const;
326 
327 private:
328  struct _Edge{
329  _Edge(GfVec2i const & verts_ = GfVec2i(-1), int index_ = -1)
330  : verts(verts_)
331  , index(index_)
332  {
333  // Simplify sorting and searching by keeping the vertices ordered.
334  if (verts[0] > verts[1]) {
335  std::swap(verts[0], verts[1]);
336  }
337  }
338  GfVec2i verts;
339  int index;
340 
341  };
342 
343  struct _CompareEdgeVertices {
344  bool operator() (_Edge const &lhs, _Edge const & rhs) const {
345  return (lhs.verts[0] < rhs.verts[0] ||
346  (lhs.verts[0] == rhs.verts[0] &&
347  lhs.verts[1] < rhs.verts[1]));
348  }
349  };
350 
351  struct _EdgeVerticesHash {
352  // Use a custom hash so that edges (a,b) and (b,a) are equivalent
353  inline size_t operator()(GfVec2i const& v) const {
354  // Triangular numbers for 2-d hash.
355  int theMin = v[0], theMax = v[1];
356  if (theMin > theMax) {
357  std::swap(theMin, theMax);
358  }
359  size_t x = theMin;
360  size_t y = x + theMax;
361  return x + (y * (y + 1)) / 2;
362  }
363  };
364 
365  std::vector<GfVec2i> _edgeVertices;
366  std::vector<_Edge> _edgesByIndex;
367 };
368 
375 {
376 public:
377  static int const NumIndicesPerQuad = 4;
378  static int const NumIndicesPerTriQuad = 6;
379 
380  HdMeshTriQuadBuilder(int * indicesBuffer, bool triangulate)
381  : _outputPtr(indicesBuffer)
382  , _triangulate(triangulate)
383  { }
384 
385  void EmitQuadFace(GfVec4i const & quadIndices) {
386  if (_triangulate) {
387  *_outputPtr++ = quadIndices[0];
388  *_outputPtr++ = quadIndices[1];
389  *_outputPtr++ = quadIndices[2];
390  *_outputPtr++ = quadIndices[2];
391  *_outputPtr++ = quadIndices[3];
392  *_outputPtr++ = quadIndices[0];
393  } else {
394  *_outputPtr++ = quadIndices[0];
395  *_outputPtr++ = quadIndices[1];
396  *_outputPtr++ = quadIndices[2];
397  *_outputPtr++ = quadIndices[3];
398  }
399  }
400 
401 private:
402  int * _outputPtr;
403  bool const _triangulate;
404 };
405 
406 
407 PXR_NAMESPACE_CLOSE_SCOPE
408 
409 #endif // PXR_IMAGING_HD_MESH_UTIL_H
Basic type for a vector of 4 int components.
Definition: vec4i.h:60
HD_API void ComputeTriQuadIndices(VtIntArray *indices, VtIntArray *primitiveParams, VtVec2iArray *edgeIndices=nullptr) const
Return triquad indices (triangulated after quadrangulation) of the input topology.
Basic type for a vector of 2 int components.
Definition: vec2i.h:60
HD_API bool ComputeQuadrangulatedFaceVaryingPrimvar(void const *source, int numElements, HdType dataType, VtValue *quadrangulated) const
Return a quadrangulation of a face-varying primvar.
HD_API void ComputeQuadIndices(VtIntArray *indices, VtIntArray *primitiveParams, VtVec2iArray *edgeIndices=nullptr) const
Return quadrangulated indices of the input topology.
A helper class for quadrangulation computation.
Definition: meshUtil.h:65
Mesh edges are described as a pair of adjacent vertices encoded as GfVec2i.
Definition: meshUtil.h:312
HD_API void ComputeTriangleIndices(VtVec3iArray *indices, VtIntArray *primitiveParams, VtIntArray *edgeIndices=nullptr) const
Return a triangulation of the input topology.
HD_API bool ComputeTriangulatedFaceVaryingPrimvar(void const *source, int numElements, HdType dataType, VtValue *triangulated) const
Return a triangulation of a face-varying primvar.
HD_API bool ComputeQuadrangulatedPrimvar(HdQuadInfo const *qi, void const *source, int numElements, HdType dataType, VtValue *quadrangulated) const
Return a quadrangulation of a per-vertex primvar.
void swap(UsdStageLoadRules &l, UsdStageLoadRules &r)
Swap the contents of rules l and r.
HD_API void EnumerateEdges(std::vector< GfVec2i > *edgeVerticesOut) const
Return a buffer filled with face vertex index pairs corresponding to the sequence in which edges are ...
A path value used to locate objects in layers or scenegraphs.
Definition: path.h:290
bool IsAllQuads() const
Returns true if the mesh is all-quads.
Definition: meshUtil.h:69
HD_API void ComputeQuadInfo(HdQuadInfo *quadInfo) const
Generate a quadInfo struct for the input topology.
Topology data for meshes.
Definition: meshTopology.h:55
Provides a container which may hold any type, and provides introspection and iteration over array typ...
Definition: value.h:166
A collection of utility algorithms for generating triangulation and quadrangulation of an input topol...
Definition: meshUtil.h:82
Helper class for emitting a buffer of quad indices, optionally splitting each quad into two triangles...
Definition: meshUtil.h:374