1 // 2 // Copyright 2015 DreamWorks Animation LLC. 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 OPENSUBDIV3_FAR_TOPOLOGY_LEVEL_H 25 #define OPENSUBDIV3_FAR_TOPOLOGY_LEVEL_H 26 27 #include "../version.h" 28 29 #include "../vtr/level.h" 30 #include "../vtr/refinement.h" 31 #include "../far/types.h" 32 33 #include <vector> 34 35 namespace OpenSubdiv { 36 namespace OPENSUBDIV_VERSION { 37 38 namespace Far { 39 40 /// 41 /// \brief An interface for accessing data in a specific level of a refined topology hierarchy. 42 /// 43 /// TopologyLevel provides an interface to data in a specific level of a topology hierarchy. 44 /// Instances of TopologyLevel are created and owned by a TopologyRefiner, 45 /// which will return const-references to them. Such references are only valid during the 46 /// lifetime of the TopologyRefiner that created and returned them, and only for a given refinement, 47 /// i.e. if the TopologyRefiner is re-refined, any references to TopoologyLevels are invalidated. 48 /// 49 class TopologyLevel { 50 51 public: 52 //@{ 53 /// @name Methods to inspect the overall inventory of components: 54 /// 55 /// All three main component types are indexed locally within each level. For 56 /// some topological relationships -- notably face-vertices, which is often 57 /// the only relationship of interest -- the total number of entries is also 58 /// made available. 59 /// 60 61 /// \brief Return the number of vertices in this level GetNumVertices()62 int GetNumVertices() const { return _level->getNumVertices(); } 63 64 /// \brief Return the number of faces in this level GetNumFaces()65 int GetNumFaces() const { return _level->getNumFaces(); } 66 67 /// \brief Return the number of edges in this level GetNumEdges()68 int GetNumEdges() const { return _level->getNumEdges(); } 69 70 /// \brief Return the total number of face-vertices, i.e. the sum of all vertices for all faces GetNumFaceVertices()71 int GetNumFaceVertices() const { return _level->getNumFaceVerticesTotal(); } 72 //@} 73 74 //@{ 75 /// @name Methods to inspect topological relationships for individual components: 76 /// 77 /// With three main component types (vertices, faces and edges), for each of the 78 /// three components the TopologyLevel stores the incident/adjacent components of 79 /// the other two types. So there are six relationships available for immediate 80 /// inspection. All are accessed by methods that return an array of fixed size 81 /// containing the indices of the incident components. 82 /// 83 /// For some of the relations, i.e. those for which the incident components are 84 /// of higher order or 'contain' the component itself (e.g. a vertex has incident 85 /// faces that contain it), an additional 'local index' is available that identifies 86 /// the component within each of its neighbors. For example, if vertex V is the k'th 87 /// vertex in some face F, then when F occurs in the set of incident vertices of V, 88 /// the local index corresponding to F will be k. The ordering of local indices 89 /// matches the ordering of the incident component to which it corresponds. 90 // 91 92 /// \brief Access the vertices incident a given face GetFaceVertices(Index f)93 ConstIndexArray GetFaceVertices(Index f) const { return _level->getFaceVertices(f); } 94 95 /// \brief Access the edges incident a given face GetFaceEdges(Index f)96 ConstIndexArray GetFaceEdges(Index f) const { return _level->getFaceEdges(f); } 97 98 /// \brief Access the vertices incident a given edge GetEdgeVertices(Index e)99 ConstIndexArray GetEdgeVertices(Index e) const { return _level->getEdgeVertices(e); } 100 101 /// \brief Access the faces incident a given edge GetEdgeFaces(Index e)102 ConstIndexArray GetEdgeFaces(Index e) const { return _level->getEdgeFaces(e); } 103 104 /// \brief Access the faces incident a given vertex GetVertexFaces(Index v)105 ConstIndexArray GetVertexFaces(Index v) const { return _level->getVertexFaces(v); } 106 107 /// \brief Access the edges incident a given vertex GetVertexEdges(Index v)108 ConstIndexArray GetVertexEdges(Index v) const { return _level->getVertexEdges(v); } 109 110 /// \brief Access the local indices of a vertex with respect to its incident faces GetVertexFaceLocalIndices(Index v)111 ConstLocalIndexArray GetVertexFaceLocalIndices(Index v) const { return _level->getVertexFaceLocalIndices(v); } 112 113 /// \brief Access the local indices of a vertex with respect to its incident edges GetVertexEdgeLocalIndices(Index v)114 ConstLocalIndexArray GetVertexEdgeLocalIndices(Index v) const { return _level->getVertexEdgeLocalIndices(v); } 115 116 /// \brief Access the local indices of an edge with respect to its incident faces GetEdgeFaceLocalIndices(Index e)117 ConstLocalIndexArray GetEdgeFaceLocalIndices(Index e) const { return _level->getEdgeFaceLocalIndices(e); } 118 119 /// \brief Identify the edge matching the given vertex pair FindEdge(Index v0,Index v1)120 Index FindEdge(Index v0, Index v1) const { return _level->findEdge(v0, v1); } 121 //@} 122 123 //@{ 124 /// @name Methods to inspect other topological properties of individual components: 125 /// 126 127 /// \brief Return if the edge is non-manifold IsEdgeNonManifold(Index e)128 bool IsEdgeNonManifold(Index e) const { return _level->isEdgeNonManifold(e); } 129 130 /// \brief Return if the vertex is non-manifold IsVertexNonManifold(Index v)131 bool IsVertexNonManifold(Index v) const { return _level->isVertexNonManifold(v); } 132 133 /// \brief Return if the edge is a boundary IsEdgeBoundary(Index e)134 bool IsEdgeBoundary(Index e) const { return _level->getEdgeTag(e)._boundary; } 135 136 /// \brief Return if the vertex is a boundary IsVertexBoundary(Index v)137 bool IsVertexBoundary(Index v) const { return _level->getVertexTag(v)._boundary; } 138 //@} 139 140 //@{ 141 /// @name Methods to inspect feature tags for individual components: 142 /// 143 /// While only a subset of components may have been tagged with features such 144 /// as sharpness, all such features have a default value and so all components 145 /// can be inspected. 146 147 /// \brief Return the sharpness assigned a given edge GetEdgeSharpness(Index e)148 float GetEdgeSharpness(Index e) const { return _level->getEdgeSharpness(e); } 149 150 /// \brief Return the sharpness assigned a given vertex GetVertexSharpness(Index v)151 float GetVertexSharpness(Index v) const { return _level->getVertexSharpness(v); } 152 153 /// \brief Return if a given face has been tagged as a hole IsFaceHole(Index f)154 bool IsFaceHole(Index f) const { return _level->isFaceHole(f); } 155 156 /// \brief Return the subdivision rule assigned a given vertex specific to this level GetVertexRule(Index v)157 Sdc::Crease::Rule GetVertexRule(Index v) const { return _level->getVertexRule(v); } 158 //@} 159 160 //@{ 161 /// @name Methods to inspect face-varying data: 162 /// 163 /// Face-varying data is organized into topologically independent channels, 164 /// each with an integer identifier. Access to face-varying data generally 165 /// requires the specification of a channel, though with a single channel 166 /// being a common situation the first/only channel will be assumed if 167 /// unspecified. 168 /// 169 /// A face-varying channel is composed of a set of values that may be shared 170 /// by faces meeting at a common vertex. Just as there are sets of vertices 171 /// that are associated with faces by index (ranging from 0 to 172 /// num-vertices - 1), face-varying values are also referenced by index 173 /// (ranging from 0 to num-values -1). 174 /// 175 /// The face-varying values associated with a face are accessed similarly to 176 /// the way in which vertices associated with the face are accessed -- an 177 /// array of fixed size containing the indices for each corner is provided 178 /// for inspection, iteration, etc. 179 /// 180 /// When the face-varying topology around a vertex "matches", it has the 181 /// same limit properties and so results in the same limit surface when 182 /// collections of adjacent vertices match. Like other references to 183 /// "topology", this includes consideration of sharpness. So it may be 184 /// that face-varying values are assigned around a vertex on a boundary in 185 /// a way that appears to match, but the face-varying interpolation option 186 /// requires sharpening of that vertex in face-varying space -- the 187 /// difference in the topology of the resulting limit surfaces leading to 188 /// the query returning false for the match. The edge case is simpler in 189 /// that it only considers continuity across the edge, not the entire 190 /// neighborhood around each end vertex. 191 192 /// \brief Return the number of face-varying channels (should be same for all levels) GetNumFVarChannels()193 int GetNumFVarChannels() const { return _level->getNumFVarChannels(); } 194 195 /// \brief Return the total number of face-varying values in a particular channel 196 /// (the upper bound of a face-varying value index) 197 int GetNumFVarValues(int channel = 0) const { return _level->getNumFVarValues(channel); } 198 199 /// \brief Access the face-varying values associated with a particular face 200 ConstIndexArray GetFaceFVarValues(Index f, int channel = 0) const { 201 return _level->getFaceFVarValues(f, channel); 202 } 203 204 /// \brief Return if face-varying topology around a vertex matches 205 bool DoesVertexFVarTopologyMatch(Index v, int channel = 0) const { 206 return _level->doesVertexFVarTopologyMatch(v, channel); 207 } 208 209 /// \brief Return if face-varying topology across the edge only matches 210 bool DoesEdgeFVarTopologyMatch(Index e, int channel = 0) const { 211 return _level->doesEdgeFVarTopologyMatch(e, channel); 212 } 213 214 /// \brief Return if face-varying topology around a face matches 215 bool DoesFaceFVarTopologyMatch(Index f, int channel = 0) const { 216 return _level->doesFaceFVarTopologyMatch(f, channel); 217 } 218 219 //@} 220 221 //@{ 222 /// @name Methods to identify parent or child components in adjoining levels of refinement: 223 224 /// \brief Access the child faces (in the next level) of a given face GetFaceChildFaces(Index f)225 ConstIndexArray GetFaceChildFaces(Index f) const { return _refToChild->getFaceChildFaces(f); } 226 227 /// \brief Access the child edges (in the next level) of a given face GetFaceChildEdges(Index f)228 ConstIndexArray GetFaceChildEdges(Index f) const { return _refToChild->getFaceChildEdges(f); } 229 230 /// \brief Access the child edges (in the next level) of a given edge GetEdgeChildEdges(Index e)231 ConstIndexArray GetEdgeChildEdges(Index e) const { return _refToChild->getEdgeChildEdges(e); } 232 233 /// \brief Return the child vertex (in the next level) of a given face GetFaceChildVertex(Index f)234 Index GetFaceChildVertex( Index f) const { return _refToChild->getFaceChildVertex(f); } 235 236 /// \brief Return the child vertex (in the next level) of a given edge GetEdgeChildVertex(Index e)237 Index GetEdgeChildVertex( Index e) const { return _refToChild->getEdgeChildVertex(e); } 238 239 /// \brief Return the child vertex (in the next level) of a given vertex GetVertexChildVertex(Index v)240 Index GetVertexChildVertex(Index v) const { return _refToChild->getVertexChildVertex(v); } 241 242 /// \brief Return the parent face (in the previous level) of a given face GetFaceParentFace(Index f)243 Index GetFaceParentFace(Index f) const { return _refToParent->getChildFaceParentFace(f); } 244 //@} 245 246 //@{ 247 /// @name Debugging aides: 248 ValidateTopology()249 bool ValidateTopology() const { return _level->validateTopology(); } 250 void PrintTopology(bool children = true) const { _level->print((children && _refToChild) ? _refToChild : 0); } 251 //@} 252 253 254 private: 255 friend class TopologyRefiner; 256 257 Vtr::internal::Level const * _level; 258 Vtr::internal::Refinement const * _refToParent; 259 Vtr::internal::Refinement const * _refToChild; 260 261 public: 262 // Not intended for public use, but required by std::vector, etc... TopologyLevel()263 TopologyLevel() { } ~TopologyLevel()264 ~TopologyLevel() { } 265 }; 266 267 } // end namespace Far 268 269 } // end namespace OPENSUBDIV_VERSION 270 using namespace OPENSUBDIV_VERSION; 271 } // end namespace OpenSubdiv 272 273 #endif /* OPENSUBDIV3_FAR_TOPOLOGY_LEVEL_H */ 274