Loading...
Searching...
No Matches
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
62enum class [[nodiscard]] HdMeshComputationResult
63{
65 Error,
67 Success,
70 Unchanged
71};
72
76
78{
79public:
80 HdMeshUtil(HdMeshTopology const* topology, SdfPath const& id)
81 : _topology(topology), _id(id) {}
82 virtual ~HdMeshUtil() {}
83
84 // --------------------------------------------------------------------
96 /*
97 +--------+-------+
98 /| \ |\ |\
99 / | \ 1 | \ 2 | \
100 / | \ | \ | \
101 / | \ | \ | 2 +
102 / 0 | 1 \ | 2 \ | /
103 / | \ | \ | /
104 / | \| \|/
105 +-------+--------+-------+
106 */
107
110 HD_API
111 void ComputeTriangleIndices(VtVec3iArray *indices,
112 VtIntArray *primitiveParams,
113 VtIntArray *edgeIndices = nullptr) const;
114
120 HD_API
122 void const* source,
123 int numElements,
124 HdType dataType,
125 VtValue *triangulated) const;
126
128
129 // --------------------------------------------------------------------
144
145 /*
146 +--------+-------+
147 /| | | \
148 / | | 2 | 2 /\
149 / | | \ / \
150 / 0 | 1 |------+ 2 +
151 /\ /| | / \ /
152 / \/ | | 2 | 2 \/
153 / 0 | 0| | | /
154 +-------+--------+-------+
155 */
156
158 HD_API
159 void ComputeQuadInfo(HdQuadInfo* quadInfo) const;
160
163 HD_API
164 void ComputeQuadIndices(VtIntArray *indices,
165 VtIntArray *primitiveParams,
166 VtVec2iArray *edgeIndices = nullptr) const;
167
170 HD_API
171 void ComputeTriQuadIndices(VtIntArray *indices,
172 VtIntArray *primitiveParams,
173 VtVec2iArray *edgeIndices = nullptr) const;
174
180 HD_API
182 void const* source,
183 int numElements,
184 HdType dataType,
185 VtValue *quadrangulated) const;
186
192 HD_API
194 int numElements,
195 HdType dataType,
196 VtValue *quadrangulated) const;
197
199
210 HD_API
212 std::vector<GfVec2i> * edgeVerticesOut,
213 std::vector<int> * firstEdgeIndexForFacesOut = nullptr) const;
214
215 // --------------------------------------------------------------------
235
236 // Per-primitive coarse-face-param encoding/decoding functions
237 static int EncodeCoarseFaceParam(int faceIndex, int edgeFlag) {
238 return ((faceIndex << 2) | (edgeFlag & 3));
239 }
240 static int DecodeFaceIndexFromCoarseFaceParam(int coarseFaceParam) {
241 return (coarseFaceParam >> 2);
242 }
243 static int DecodeEdgeFlagFromCoarseFaceParam(int coarseFaceParam) {
244 return (coarseFaceParam & 3);
245 }
246
248
249private:
252 int _ComputeNumQuads(VtIntArray const &numVerts,
253 VtIntArray const &holeIndices,
254 bool *invalidFaceFound = nullptr) const;
255
257 void _ComputeQuadIndices(
258 VtIntArray *indices,
259 VtIntArray *primitiveParams,
260 VtVec2iArray *edgeIndices,
261 bool triangulate = false) const;
262
263 HdMeshTopology const* _topology;
264 SdfPath const _id;
265};
266
314{
315public:
316 HD_API
317 explicit HdMeshEdgeIndexTable(HdMeshTopology const * topology);
318 HD_API
320
321 HD_API
322 bool GetVerticesForEdgeIndex(int edgeId, GfVec2i * edgeVerticesOut) const;
323
324 HD_API
325 bool GetVerticesForEdgeIndices(
326 std::vector<int> const & edgeIndices,
327 std::vector<GfVec2i> * edgeVerticesOut) const;
328
329 HD_API
330 bool GetEdgeIndices(GfVec2i const & edgeVertices,
331 std::vector<int> * edgeIndicesOut) const;
332
334 HD_API
335 VtIntArray CollectFaceEdgeIndices(VtIntArray const &faceIndices) const;
336
337private:
338 struct _Edge{
339 _Edge(GfVec2i const & verts_ = GfVec2i(-1), int index_ = -1)
340 : verts(verts_)
341 , index(index_)
342 {
343 // Simplify sorting and searching by keeping the vertices ordered.
344 if (verts[0] > verts[1]) {
345 std::swap(verts[0], verts[1]);
346 }
347 }
348 GfVec2i verts;
349 int index;
350
351 };
352
353 struct _CompareEdgeVertices {
354 bool operator() (_Edge const &lhs, _Edge const & rhs) const {
355 return (lhs.verts[0] < rhs.verts[0] ||
356 (lhs.verts[0] == rhs.verts[0] &&
357 lhs.verts[1] < rhs.verts[1]));
358 }
359 };
360
361 struct _EdgeVerticesHash {
362 // Use a custom hash so that edges (a,b) and (b,a) are equivalent
363 inline size_t operator()(GfVec2i const& v) const {
364 // Triangular numbers for 2-d hash.
365 int theMin = v[0], theMax = v[1];
366 if (theMin > theMax) {
367 std::swap(theMin, theMax);
368 }
369 size_t x = theMin;
370 size_t y = x + theMax;
371 return x + (y * (y + 1)) / 2;
372 }
373 };
374
375 HdMeshTopology const *_topology;
376 std::vector<int> _firstEdgeIndexForFaces;
377
378 std::vector<GfVec2i> _edgeVertices;
379 std::vector<_Edge> _edgesByIndex;
380};
381
388{
389public:
390 static int const NumIndicesPerQuad = 4;
391 static int const NumIndicesPerTriQuad = 6;
392
393 HdMeshTriQuadBuilder(int * indicesBuffer, bool triangulate)
394 : _outputPtr(indicesBuffer)
395 , _triangulate(triangulate)
396 { }
397
398 void EmitQuadFace(GfVec4i const & quadIndices) {
399 if (_triangulate) {
400 *_outputPtr++ = quadIndices[0];
401 *_outputPtr++ = quadIndices[1];
402 *_outputPtr++ = quadIndices[2];
403 *_outputPtr++ = quadIndices[2];
404 *_outputPtr++ = quadIndices[3];
405 *_outputPtr++ = quadIndices[0];
406 } else {
407 *_outputPtr++ = quadIndices[0];
408 *_outputPtr++ = quadIndices[1];
409 *_outputPtr++ = quadIndices[2];
410 *_outputPtr++ = quadIndices[3];
411 }
412 }
413
414private:
415 int * _outputPtr;
416 bool const _triangulate;
417};
418
419
420PXR_NAMESPACE_CLOSE_SCOPE
421
422#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:314
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:388
A collection of utility algorithms for generating triangulation and quadrangulation of an input topol...
Definition: meshUtil.h:78
HD_API HdMeshComputationResult ComputeTriangulatedFaceVaryingPrimvar(void const *source, int numElements, HdType dataType, VtValue *triangulated) const
Perform 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:152
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