All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
fvarLevel.h
Go to the documentation of this file.
1 //
2 // Copyright 2014 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 VTR_FVAR_LEVEL_H
25 #define VTR_FVAR_LEVEL_H
26 
27 #include "../version.h"
28 
29 #include "../sdc/type.h"
30 #include "../sdc/crease.h"
31 #include "../sdc/options.h"
32 #include "../vtr/types.h"
33 #include "../vtr/level.h"
34 
35 #include <vector>
36 #include <cassert>
37 #include <cstring>
38 
39 
40 namespace OpenSubdiv {
41 namespace OPENSUBDIV_VERSION {
42 
43 // Forward declaration of friend classes:
44 namespace Far {
45  class TopologyRefiner;
46 }
47 namespace Vtr {
48  class Refinement;
49  class FVarRefinement;
50 }
51 
52 //
53 // FVarLevel:
54 // A "face-varying channel" includes the topology for a set of face-varying
55 // data, relative to the topology of the Level with which it is associated.
56 //
57 // Analogous to a set of vertices and face-vertices that define the topology for
58 // the geometry, a channel requires a set of "values" and "face-values". The
59 // "values" are indices of entries in a set of face-varying data, just as vertices
60 // are indices into a set of vertex data. The face-values identify a value for
61 // each vertex of the face, and so define topology for the values that may be
62 // unique to each channel.
63 //
64 // In addition to the value size and the vector of face-values (which matches the
65 // size of the geometry's face-vertices), tags are associated with each component
66 // to identify deviations of the face-varying topology from the vertex topology.
67 // And since there may be a one-to-many mapping between vertices and face-varying
68 // values, that mapping is also allocated.
69 //
70 // It turns out that the mapping used is able to completely encode the set of
71 // face-values and is more amenable to refinement. Currently the face-values
72 // take up almost half the memory of this representation, so if memory does
73 // become a concern, we do not need to store them. The only reason we do so now
74 // is that the face-value interface for specifying base topology and inspecting
75 // subsequent levels is very familar to that of face-vertices for clients. So
76 // having them available for such access is convenient.
77 //
78 // Regarding scope and access...
79 // Unclear at this early state, but leaning towards nesting this class within
80 // Level, given the intimate dependency between the two.
81 // Everything is being declared public for now to facilitate access until its
82 // clearer how this functionality will be provided.
83 //
84 namespace Vtr {
85 
86 class FVarLevel {
87 protected:
88  friend class Level;
89  friend class Refinement;
90  friend class FVarRefinement;
91  friend class Far::TopologyRefiner;
92 
93 protected:
96 
97  //
98  // Component tags -- trying to minimize the types needed here:
99  //
100  // Tag per Edge:
101  // - facilitates topological analysis around each vertex
102  // - required during refinement to spawn one or more edge-values
103  //
104  struct ETag {
105  ETag() { }
106 
107  void clear() { std::memset(this, 0, sizeof(ETag)); }
108 
109  typedef unsigned char ETagSize;
110 
111  ETagSize _mismatch : 1; // local FVar topology does not match
112  ETagSize _boundary : 1; // not continuous at both ends
113  ETagSize _disctsV0 : 1; // discontinuous at vertex 0
114  ETagSize _disctsV1 : 1; // discontinuous at vertex 1
115  };
116 
117  //
118  // Tag per Value:
119  // - informs both refinement and interpolation
120  // - every value spawns a child value in refinement
121  // - given ordering of values (1-per-vertex first) serves as a vertex tag
122  //
123  struct ValueTag {
124  ValueTag() { }
125 
126  void clear() { std::memset(this, 0, sizeof(ValueTag)); }
127 
128  bool isMismatch() const { return _mismatch; }
129  bool isCrease() const { return _crease; }
130  bool isCorner() const { return !_crease; }
131  bool isSemiSharp() const { return _semiSharp; }
132  bool isInfSharp() const { return !_semiSharp && !_crease; }
133  bool isDepSharp() const { return _depSharp; }
134 
135  typedef unsigned char ValueTagSize;
136 
137  ValueTagSize _mismatch : 1; // local FVar topology does not match
138  ValueTagSize _crease : 1; // value is a crease, otherwise a corner
139  ValueTagSize _semiSharp : 1; // value is a corner decaying to crease
140  ValueTagSize _depSharp : 1; // value a corner by dependency on another
141  };
142 
144 
145  //
146  // Simple struct containing the "end faces" of a crease, i.e. the faces which
147  // contain the FVar values to be used when interpolating the crease. (Prefer
148  // the struct over std::pair for its member names)
149  //
150  struct CreaseEndPair {
153  };
154 
156 
157 protected:
158  FVarLevel(Level const& level);
159  ~FVarLevel();
160 
161  // Queries for the entire channel:
162  Level const& getLevel() const { return _level; }
163 
164  int getNumValues() const { return _valueCount; }
165  int getNumFaceValuesTotal() const { return (int) _faceVertValues.size(); }
166 
167  // Queries per face:
168  IndexArray const getFaceValues(Index fIndex) const;
170 
171  // Queries per edge:
172  ETag getEdgeTag(Index eIndex) const { return _edgeTags[eIndex]; }
173  bool edgeTopologyMatches(Index eIndex) const { return !getEdgeTag(eIndex)._mismatch; }
174 
175  // Queries per vertex (and its potential sibling values):
176  int getNumVertexValues(Index v) const { return _vertSiblingCounts[v]; }
177  Index getVertexValueOffset(Index v, Sibling i = 0) const { return _vertSiblingOffsets[v] + i; }
178 
180 
181  // Methods to access/modify array properties per vertex:
182  IndexArray const getVertexValues(Index vIndex) const;
184 
185  ValueTagArray const getVertexValueTags(Index vIndex) const;
187 
190 
191  SiblingArray const getVertexFaceSiblings(Index vIndex) const;
193 
194  // Queries per value:
195  ValueTag getValueTag(Index valueIndex) const { return _vertValueTags[valueIndex]; }
196  bool valueTopologyMatches(Index valueIndex) const { return !getValueTag(valueIndex)._mismatch; }
197 
198  // Higher-level topological queries, i.e. values in a neighborhood:
199  void getEdgeFaceValues(Index eIndex, int fIncToEdge, Index valuesPerVert[2]) const;
200  void getVertexEdgeValues(Index vIndex, Index valuesPerEdge[]) const;
201  void getVertexCreaseEndValues(Index vIndex, Sibling sibling, Index endValues[2]) const;
202 
203  // Initialization and allocation helpers:
204  void setOptions(Sdc::Options const& options);
205  void resizeVertexValues(int numVertexValues);
206  void resizeValues(int numValues);
207  void resizeComponents();
208 
209  // Topological analysis methods -- tagging and face-value population:
213 
214  // Information about the "span" for a value:
215  struct ValueSpan {
220  };
221  void gatherValueSpans(Index vIndex, ValueSpan * vValueSpans) const;
222 
223  // Debugging methods:
224  bool validate() const;
225  void print() const;
226  void buildFaceVertexSiblingsFromVertexFaceSiblings(std::vector<Sibling>& fvSiblings) const;
227 
228 protected:
229  Level const & _level;
230 
231  // Options vary between channels:
233 
234  bool _isLinear;
238 
239  //
240  // Vectors recording face-varying topology including tags that help propagate
241  // data through the refinement hierarchy. Vectors are not sparse but most use
242  // 8-bit values relative to the local topology.
243  //
244  // The vector of face-values is actually redundant here, but is constructed as
245  // it is most convenient for clients. It represents almost half the memory of
246  // the topology (4 32-bit integers per face) and not surprisingly, populating
247  // it takes a considerable amount of the refinement time (1/3). We can reduce
248  // both if we are willing to compute these on demand for clients.
249  //
250  // Per-face (matches face-verts of corresponding level):
251  std::vector<Index> _faceVertValues;
252 
253  // Per-edge:
254  std::vector<ETag> _edgeTags;
255 
256  // Per-vertex:
257  std::vector<Sibling> _vertSiblingCounts;
258  std::vector<int> _vertSiblingOffsets;
259  std::vector<Sibling> _vertFaceSiblings;
260 
261  // Per-value:
262  std::vector<Index> _vertValueIndices;
263  std::vector<ValueTag> _vertValueTags;
264  std::vector<CreaseEndPair> _vertValueCreaseEnds;
265 };
266 
267 //
268 // Access/modify the values associated with each face:
269 //
270 inline IndexArray const
272 
273  int vCount = _level._faceVertCountsAndOffsets[fIndex*2];
274  int vOffset = _level._faceVertCountsAndOffsets[fIndex*2+1];
275  return IndexArray(&_faceVertValues[vOffset], vCount);
276 }
277 inline IndexArray
279 
280  int vCount = _level._faceVertCountsAndOffsets[fIndex*2];
281  int vOffset = _level._faceVertCountsAndOffsets[fIndex*2+1];
282  return IndexArray(&_faceVertValues[vOffset], vCount);
283 }
284 
285 inline FVarLevel::SiblingArray const
287 
288  int vCount = _level._vertFaceCountsAndOffsets[vIndex*2];
289  int vOffset = _level._vertFaceCountsAndOffsets[vIndex*2+1];
290  return SiblingArray(&_vertFaceSiblings[vOffset], vCount);
291 }
294 
295  int vCount = _level._vertFaceCountsAndOffsets[vIndex*2];
296  int vOffset = _level._vertFaceCountsAndOffsets[vIndex*2+1];
297  return SiblingArray(&_vertFaceSiblings[vOffset], vCount);
298 }
299 
300 inline IndexArray const
302 {
303  int vCount = getNumVertexValues(vIndex);
304  int vOffset = getVertexValueOffset(vIndex);
305  return IndexArray(&_vertValueIndices[vOffset], vCount);
306 }
307 inline IndexArray
309 {
310  int vCount = getNumVertexValues(vIndex);
311  int vOffset = getVertexValueOffset(vIndex);
312  return IndexArray(&_vertValueIndices[vOffset], vCount);
313 }
314 
315 inline FVarLevel::ValueTagArray const
317 {
318  int vCount = getNumVertexValues(vIndex);
319  int vOffset = getVertexValueOffset(vIndex);
320  return ValueTagArray(&_vertValueTags[vOffset], vCount);
321 }
324 {
325  int vCount = getNumVertexValues(vIndex);
326  int vOffset = getVertexValueOffset(vIndex);
327  return ValueTagArray(&_vertValueTags[vOffset], vCount);
328 }
329 
332 {
333  int vCount = getNumVertexValues(vIndex);
334  int vOffset = getVertexValueOffset(vIndex);
335  return CreaseEndPairArray(&_vertValueCreaseEnds[vOffset], vCount);
336 }
339 {
340  int vCount = getNumVertexValues(vIndex);
341  int vOffset = getVertexValueOffset(vIndex);
342  return CreaseEndPairArray(&_vertValueCreaseEnds[vOffset], vCount);
343 }
344 
345 } // end namespace Vtr
346 
347 } // end namespace OPENSUBDIV_VERSION
348 using namespace OPENSUBDIV_VERSION;
349 } // end namespace OpenSubdiv
350 
351 #endif /* VTR_FVAR_LEVEL_H */
352 
ValueTagArray const getVertexValueTags(Index vIndex) const
Definition: fvarLevel.h:316
Vtr::Array< CreaseEndPair > CreaseEndPairArray
Definition: fvarLevel.h:155
void setOptions(Sdc::Options const &options)
IndexArray const getVertexValues(Index vIndex) const
Definition: fvarLevel.h:301
bool valueTopologyMatches(Index valueIndex) const
Definition: fvarLevel.h:196
void resizeVertexValues(int numVertexValues)
Index getVertexValueOffset(Index v, Sibling i=0) const
Definition: fvarLevel.h:177
void buildFaceVertexSiblingsFromVertexFaceSiblings(std::vector< Sibling > &fvSiblings) const
CreaseEndPairArray const getVertexValueCreaseEnds(Index vIndex) const
Definition: fvarLevel.h:331
std::vector< Index > _faceVertCountsAndOffsets
Definition: level.h:405
std::vector< Index > _vertFaceCountsAndOffsets
Definition: level.h:419
ValueTag getValueTag(Index valueIndex) const
Definition: fvarLevel.h:195
Stores topology data for a specified set of refinement options.
std::vector< CreaseEndPair > _vertValueCreaseEnds
Definition: fvarLevel.h:264
IndexArray const getFaceValues(Index fIndex) const
Definition: fvarLevel.h:271
Index getVertexValue(Index v, Sibling i=0) const
Definition: fvarLevel.h:179
void getVertexCreaseEndValues(Index vIndex, Sibling sibling, Index endValues[2]) const
SiblingArray const getVertexFaceSiblings(Index vIndex) const
Definition: fvarLevel.h:286
void gatherValueSpans(Index vIndex, ValueSpan *vValueSpans) const
void getVertexEdgeValues(Index vIndex, Index valuesPerEdge[]) const
void getEdgeFaceValues(Index eIndex, int fIncToEdge, Index valuesPerVert[2]) const
bool edgeTopologyMatches(Index eIndex) const
Definition: fvarLevel.h:173