All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
meshUtil.h
1//
2// Copyright 2017 Pixar
3//
4// Licensed under the terms set forth in the LICENSE.txt file available at
5// https://openusd.org/license.
6//
7#ifndef PXR_IMAGING_HD_MESH_UTIL_H
8#define PXR_IMAGING_HD_MESH_UTIL_H
9
10#include "pxr/pxr.h"
11#include "pxr/imaging/hd/api.h"
12#include "pxr/imaging/hd/version.h"
13#include "pxr/imaging/hd/types.h"
14#include "pxr/imaging/hd/meshTopology.h"
15
16#include "pxr/usd/sdf/path.h"
17
18#include "pxr/base/gf/vec2i.h"
19#include "pxr/base/gf/vec3i.h"
20#include "pxr/base/gf/vec4i.h"
21
22#include "pxr/base/vt/array.h"
23#include "pxr/base/vt/value.h"
24
25PXR_NAMESPACE_OPEN_SCOPE
26
29
30// v0 v2
31// +-----e2----+
32// \ | /
33// \ __c__ /
34// e0 e1
35// \ /
36// \ /
37// + v1
38//
39//
40// original points additional center and edge points
41// +------------ ... ----+--------------------------------+
42// | v0 v1 v2 vn | e0 e1 e2 c0, e3 e4 e5 c1 ... |
43// +------------ ... ----+--------------------------------+
44// ^
45// pointsOffset
46// <----- numAdditionalPoints ---->
47
48struct HdQuadInfo {
49 HdQuadInfo() : pointsOffset(0), numAdditionalPoints(0), maxNumVert(0) { }
50
52 bool IsAllQuads() const { return numAdditionalPoints == 0; }
53
54 int pointsOffset;
55 int numAdditionalPoints;
56 int maxNumVert;
57 std::vector<int> numVerts; // num vertices of non-quads
58 std::vector<int> verts; // vertex indices of non-quads
59};
60
64
66{
67public:
68 HdMeshUtil(HdMeshTopology const* topology, SdfPath const& id)
69 : _topology(topology), _id(id) {}
70 virtual ~HdMeshUtil() {}
71
72 // --------------------------------------------------------------------
84 /*
85 +--------+-------+
86 /| \ |\ |\
87 / | \ 1 | \ 2 | \
88 / | \ | \ | \
89 / | \ | \ | 2 +
90 / 0 | 1 \ | 2 \ | /
91 / | \ | \ | /
92 / | \| \|/
93 +-------+--------+-------+
94 */
95
98 HD_API
99 void ComputeTriangleIndices(VtVec3iArray *indices,
100 VtIntArray *primitiveParams,
101 VtIntArray *edgeIndices = nullptr) const;
102
108 HD_API
110 int numElements,
111 HdType dataType,
112 VtValue *triangulated) const;
113
115
116 // --------------------------------------------------------------------
131
132 /*
133 +--------+-------+
134 /| | | \
135 / | | 2 | 2 /\
136 / | | \ / \
137 / 0 | 1 |------+ 2 +
138 /\ /| | / \ /
139 / \/ | | 2 | 2 \/
140 / 0 | 0| | | /
141 +-------+--------+-------+
142 */
143
145 HD_API
146 void ComputeQuadInfo(HdQuadInfo* quadInfo) const;
147
150 HD_API
151 void ComputeQuadIndices(VtIntArray *indices,
152 VtIntArray *primitiveParams,
153 VtVec2iArray *edgeIndices = nullptr) const;
154
157 HD_API
158 void ComputeTriQuadIndices(VtIntArray *indices,
159 VtIntArray *primitiveParams,
160 VtVec2iArray *edgeIndices = nullptr) const;
161
167 HD_API
169 void const* source,
170 int numElements,
171 HdType dataType,
172 VtValue *quadrangulated) const;
173
179 HD_API
181 int numElements,
182 HdType dataType,
183 VtValue *quadrangulated) const;
184
186
197 HD_API
199 std::vector<GfVec2i> * edgeVerticesOut,
200 std::vector<int> * firstEdgeIndexForFacesOut = nullptr) const;
201
202 // --------------------------------------------------------------------
222
223 // Per-primitive coarse-face-param encoding/decoding functions
224 static int EncodeCoarseFaceParam(int faceIndex, int edgeFlag) {
225 return ((faceIndex << 2) | (edgeFlag & 3));
226 }
227 static int DecodeFaceIndexFromCoarseFaceParam(int coarseFaceParam) {
228 return (coarseFaceParam >> 2);
229 }
230 static int DecodeEdgeFlagFromCoarseFaceParam(int coarseFaceParam) {
231 return (coarseFaceParam & 3);
232 }
233
235
236private:
239 int _ComputeNumQuads(VtIntArray const &numVerts,
240 VtIntArray const &holeIndices,
241 bool *invalidFaceFound = nullptr) const;
242
244 void _ComputeQuadIndices(
245 VtIntArray *indices,
246 VtIntArray *primitiveParams,
247 VtVec2iArray *edgeIndices,
248 bool triangulate = false) const;
249
250 HdMeshTopology const* _topology;
251 SdfPath const _id;
252};
253
301{
302public:
303 HD_API
304 explicit HdMeshEdgeIndexTable(HdMeshTopology const * topology);
305 HD_API
307
308 HD_API
309 bool GetVerticesForEdgeIndex(int edgeId, GfVec2i * edgeVerticesOut) const;
310
311 HD_API
312 bool GetVerticesForEdgeIndices(
313 std::vector<int> const & edgeIndices,
314 std::vector<GfVec2i> * edgeVerticesOut) const;
315
316 HD_API
317 bool GetEdgeIndices(GfVec2i const & edgeVertices,
318 std::vector<int> * edgeIndicesOut) const;
319
321 HD_API
322 VtIntArray CollectFaceEdgeIndices(VtIntArray const &faceIndices) const;
323
324private:
325 struct _Edge{
326 _Edge(GfVec2i const & verts_ = GfVec2i(-1), int index_ = -1)
327 : verts(verts_)
328 , index(index_)
329 {
330 // Simplify sorting and searching by keeping the vertices ordered.
331 if (verts[0] > verts[1]) {
332 std::swap(verts[0], verts[1]);
333 }
334 }
335 GfVec2i verts;
336 int index;
337
338 };
339
340 struct _CompareEdgeVertices {
341 bool operator() (_Edge const &lhs, _Edge const & rhs) const {
342 return (lhs.verts[0] < rhs.verts[0] ||
343 (lhs.verts[0] == rhs.verts[0] &&
344 lhs.verts[1] < rhs.verts[1]));
345 }
346 };
347
348 struct _EdgeVerticesHash {
349 // Use a custom hash so that edges (a,b) and (b,a) are equivalent
350 inline size_t operator()(GfVec2i const& v) const {
351 // Triangular numbers for 2-d hash.
352 int theMin = v[0], theMax = v[1];
353 if (theMin > theMax) {
354 std::swap(theMin, theMax);
355 }
356 size_t x = theMin;
357 size_t y = x + theMax;
358 return x + (y * (y + 1)) / 2;
359 }
360 };
361
362 HdMeshTopology const *_topology;
363 std::vector<int> _firstEdgeIndexForFaces;
364
365 std::vector<GfVec2i> _edgeVertices;
366 std::vector<_Edge> _edgesByIndex;
367};
368
375{
376public:
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
401private:
402 int * _outputPtr;
403 bool const _triangulate;
404};
405
406
407PXR_NAMESPACE_CLOSE_SCOPE
408
409#endif // PXR_IMAGING_HD_MESH_UTIL_H
Basic type for a vector of 2 int components.
Definition: vec2i.h:44
Basic type for a vector of 4 int components.
Definition: vec4i.h:44
Mesh edges are described as a pair of adjacent vertices encoded as GfVec2i.
Definition: meshUtil.h:301
HD_API VtIntArray CollectFaceEdgeIndices(VtIntArray const &faceIndices) const
Returns the edge indices for all faces in faceIndices.
Topology data for meshes.
Definition: meshTopology.h:38
Helper class for emitting a buffer of quad indices, optionally splitting each quad into two triangles...
Definition: meshUtil.h:375
A collection of utility algorithms for generating triangulation and quadrangulation of an input topol...
Definition: meshUtil.h:66
HD_API bool ComputeTriangulatedFaceVaryingPrimvar(void const *source, int numElements, HdType dataType, VtValue *triangulated) const
Return a triangulation of a face-varying primvar.
HD_API void ComputeTriangleIndices(VtVec3iArray *indices, VtIntArray *primitiveParams, VtIntArray *edgeIndices=nullptr) const
Return a triangulation of the input topology.
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.
HD_API void ComputeTriQuadIndices(VtIntArray *indices, VtIntArray *primitiveParams, VtVec2iArray *edgeIndices=nullptr) const
Return triquad indices (triangulated after quadrangulation) of the input topology.
HD_API void ComputeQuadInfo(HdQuadInfo *quadInfo) const
Generate a quadInfo struct for the input topology.
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.
HD_API void EnumerateEdges(std::vector< GfVec2i > *edgeVerticesOut, std::vector< int > *firstEdgeIndexForFacesOut=nullptr) 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:274
Provides a container which may hold any type, and provides introspection and iteration over array typ...
Definition: value.h:147
A helper class for quadrangulation computation.
Definition: meshUtil.h:48
bool IsAllQuads() const
Returns true if the mesh is all-quads.
Definition: meshUtil.h:52