HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
meshTopologyValidation.h
Go to the documentation of this file.
1 //
2 // Copyright 2020 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 
25 
26 #ifndef PXR_IMAGING_PX_OSD_MESH_TOPOLOGY_VALIDATION_H
27 #define PXR_IMAGING_PX_OSD_MESH_TOPOLOGY_VALIDATION_H
28 
30 
31 #include <array>
32 #include <memory>
33 
35 
36 class PxOsdMeshTopology;
37 
38 /// Utility to help validate an OpenSubdiv Mesh topology.
39 ///
40 /// This class is created by PxOsdMeshTopology's Validate method.
41 ///
42 /// Internally, this will avoid dynamic allocations as long as
43 /// the topology is valid (currently using std::unique_ptr but
44 /// targeting std::optional for C++17).
45 ///
46 /// This class does a set of basic validation tests on
47 /// the topology of a mesh. This set of tests isn't necessarily
48 /// complete. There are other cases like invalid primvar size
49 /// that this will not check for.
50 ///
51 /// Topology is considered valid if it passes a series of checks
52 /// enumerated by the Code class enum.
53 ///
54 /// \warn This doesn't currently validate that the topology of crease
55 /// indices match valid edges.
56 ///
57 /// \note This class is convertable to bool and converts to true if the
58 /// the topology is valid and false if any invalidations were found.
59 /// That is to say, a conversion to true implies an empty invalidation
60 /// vector and false implies a non-empty invalidation vector.
62 public:
63  friend class PxOsdMeshTopology;
64  /// Codes for various invalid states for PxOsdMeshTopology
65  enum class Code {
66  /// Encodes invalid scheme token value
68  /// Encodes invalid orientation token value
70  /// Encodes invalid triangle subdivision token value
72  /// Encodes invalid vertex interpolation rule token value
74  /// Encodes invalid face varying interpolation rule token value
76  /// Encodes invalid crease method token value
78  /// Encodes crease lengths element less than 2
80  /// Encodes crease indices size not matching the sum of the lengths
81  /// array
83  /// Encodes crease indices element is not in the face vertex indices
84  /// vector
86  /// Encodes if crease weights is the size of the number of creases or
87  /// the number of crease edges
89  /// Encodes if crease weights are negative
91  /// Encodes corner indices element is not in the face vertex indices
92  /// vector
94  /// Encodes if corner weights are negative
96  /// Encodes if corner weights is not the size of the number of corner
97  /// indices
99  /// Encodes if the hole indices are negative or greater than the maximum
100  /// face index (face count - 1)
102  /// Encodes if a vertex count is less than 3
104  /// Encodes if the element is negative
106  /// Encodes if the indices size does not match the sum of the face
107  /// vertex counts array
109  };
110  /// A tuple containing a code describing an invalidation and a descriptive
111  /// message
112  struct Invalidation {
115  };
116 private:
117  // TODO: In C++17, this class is uncessary and should be replaced with
118  // std::optional<std::vector<Invalidation>>
119  class _OptionalInvalidationVector {
120  std::unique_ptr<std::vector<Invalidation>> _value;
121 
122  public:
123  _OptionalInvalidationVector() = default;
124  _OptionalInvalidationVector(_OptionalInvalidationVector&&) = default;
125  _OptionalInvalidationVector& operator=(_OptionalInvalidationVector&&) =
126  default;
127  _OptionalInvalidationVector(_OptionalInvalidationVector const& other)
128  : _value(nullptr) {
129  if (other._value) {
130  _value.reset(new std::vector<Invalidation>(*other._value));
131  }
132  }
133  _OptionalInvalidationVector& operator=(
134  _OptionalInvalidationVector const& other) {
135  _value = nullptr;
136  if (other._value) {
137  _value.reset(new std::vector<Invalidation>(*other._value));
138  }
139  return *this;
140  }
141  void emplace() { _value.reset(new std::vector<Invalidation>); }
142  explicit operator bool() const { return _value != nullptr; }
143  std::vector<Invalidation>& value() {
144  TF_DEV_AXIOM(*this);
145  return *_value;
146  }
147  std::vector<Invalidation> const& value() const {
148  TF_DEV_AXIOM(*this);
149  return *_value;
150  }
151  };
152 
153  _OptionalInvalidationVector _invalidations;
154  template <size_t S>
155  void _ValidateToken(PxOsdMeshTopologyValidation::Code code,
156  const char* name, const TfToken& token,
157  const std::array<TfToken, S>& validTokens);
158  /// initializes the vector if necessary
159  void _AppendInvalidation(const Invalidation& invalidation) {
160  if (!_invalidations) {
161  _invalidations.emplace();
162  }
163  _invalidations.value().push_back(invalidation);
164  }
166 
167 public:
168  PxOsdMeshTopologyValidation() = default;
171  default;
173  default;
175  PxOsdMeshTopologyValidation const& other) = default;
176 
177  /// Return true if the topology is valid
178  explicit operator bool() const {
179  return !_invalidations || _invalidations.value().empty();
180  }
181 
182  using iterator = std::vector<Invalidation>::const_iterator;
183  using const_iterator = std::vector<Invalidation>::const_iterator;
184 
185  /// Returns an iterator for the beginning of the invalidation vector
186  /// if it has been initialized. Otherwise, returns an empty iterator.
188  return _invalidations ? _invalidations.value().cbegin()
189  : const_iterator();
190  }
191  /// Returns an iterator for the end of the invalidation vector
192  /// if it has been initialized. Otherwise, returns an empty iterator.
193  const_iterator end() const {
194  return _invalidations ? _invalidations.value().cend()
195  : const_iterator();
196  }
197 
198  /// Returns an iterator for the beginning of the invalidation vector
199  /// if it has been initialized. Otherwise, returns an empty iterator.
201  return _invalidations ? _invalidations.value().cbegin()
202  : const_iterator();
203  }
204  /// Returns an iterator for the end of the invalidation vector
205  /// if it has been initialized. Otherwise, returns an empty iterator.
207  return _invalidations ? _invalidations.value().cend()
208  : const_iterator();
209  }
210 private:
211  void _ValidateScheme(PxOsdMeshTopology const&);
212  void _ValidateOrientation(PxOsdMeshTopology const&);
213  void _ValidateTriangleSubdivision(PxOsdMeshTopology const&);
214  void _ValidateVertexInterpolation(PxOsdMeshTopology const&);
215  void _ValidateFaceVaryingInterpolation(PxOsdMeshTopology const&);
216  void _ValidateCreaseMethod(PxOsdMeshTopology const&);
217  void _ValidateCreasesAndCorners(PxOsdMeshTopology const&);
218  void _ValidateHoles(PxOsdMeshTopology const&);
219  void _ValidateFaceVertexCounts(PxOsdMeshTopology const&);
220  void _ValidateFaceVertexIndices(PxOsdMeshTopology const&);
221 };
222 
224 
225 #endif
Encodes invalid triangle subdivision token value.
std::vector< Invalidation >::const_iterator iterator
PxOsdMeshTopologyValidation & operator=(PxOsdMeshTopologyValidation &&)=default
GLsizei const GLchar *const * string
Definition: glcorearb.h:814
GLsizei const GLfloat * value
Definition: glcorearb.h:824
const_iterator cbegin() const
Encodes invalid face varying interpolation rule token value.
Encodes invalid crease method token value.
#define TF_DEV_AXIOM(cond)
Definition: token.h:87
Encodes if crease weights are negative.
Encodes invalid vertex interpolation rule token value.
Code
Codes for various invalid states for PxOsdMeshTopology.
std::vector< Invalidation >::const_iterator const_iterator
GLuint const GLchar * name
Definition: glcorearb.h:786
Encodes invalid scheme token value.
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1441
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:91
Encodes invalid orientation token value.
Encodes if corner weights are negative.
Encodes crease lengths element less than 2.