All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
refinement.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_REFINEMENT_H
25 #define VTR_REFINEMENT_H
26 
27 #include "../version.h"
28 
29 #include "../sdc/type.h"
30 #include "../sdc/options.h"
31 #include "../vtr/types.h"
32 #include "../vtr/level.h"
33 
34 #include <vector>
35 
36 //
37 // Declaration for the main refinement class (Refinement) and its pre-requisites:
38 //
39 namespace OpenSubdiv {
40 namespace OPENSUBDIV_VERSION {
41 
42 namespace Far {
43  class TopologyRefiner;
44  class PatchTablesFactory;
45 }
46 
47 namespace Vtr {
48 
49 class SparseSelector;
50 class FVarRefinement;
51 
52 //
53 // Refinement:
54 // A refinement is a mapping between two levels -- relating the components in the original
55 // (parent) level to the one refined (child). The refinement may be complete (uniform) or sparse
56 // (adaptive or otherwise selective), so not all components in the parent level will spawn
57 // components in the child level.
58 //
59 // Refinement is an abstract class and expects subclasses corresponding to the different types
60 // of topological splits that the supported subdivisions schemes collectively require, i.e. those
61 // list in Sdc::SplitType. Note the virtual requirements expected of the subclasses in the list
62 // of protected methods -- they differ mainly in the topology that is created in the child Level
63 // and not the propagation of tags through refinement, subdivision of sharpness values of the
64 // treatment of face-varying data. The primary subclasses are QuadRefinement and TriRefinement.
65 //
66 // At a high level, all that is necessary in terms of interface is to construct, initialize
67 // (linking the two levels), optionally select components for sparse refinement (via use of the
68 // SparseSelector) and call the refine() method. This usage is expected of Far::TopologyRefiner.
69 //
70 // Since we really want this class to be restricted from public access eventually, all methods
71 // begin with lower case (as is the convention for protected methods) and the list of friends
72 // will be maintained more strictly.
73 //
74 class Refinement {
75 
76 public:
77  Refinement(Level const & parent, Level & child, Sdc::Options const& schemeOptions);
78  virtual ~Refinement();
79 
80  Level const& parent() const { return *_parent; }
81  Level const& child() const { return *_child; }
82  Level& child() { return *_child; }
83 
84  //
85  // Options associated with the actual refinement operation, which are going to get
86  // quite involved to ensure that the refinement of data that is not of interest can
87  // be suppressed. For now we have:
88  //
89  // "sparse": the alternative to uniform refinement, which requires that
90  // components be previously selected/marked to be included.
91  //
92  // "face topology only": this is one that may get broken down into a finer
93  // set of options. It suppresses "full topology" in the child level
94  // and only generates what is necessary to define the list of faces.
95  // This is only one of the six possible topological relations that
96  // can be generated -- we may eventually want a flag for each.
97  //
98  // "compute masks": this is intended to be temporary, along with the data
99  // members associated with it -- it will trigger the computation and
100  // storage of mask weights for all child vertices. This is naively
101  // stored at this point and exists only for reference.
102  //
103  // Its still up for debate as to how finely these should be controlled, e.g.
104  // for sparse refinement, we likely want full topology at the finest level to
105  // allow for subsequent patch construction...
106  //
107  struct Options {
108  Options() : _sparse(0),
110  { }
111 
112  unsigned int _sparse : 1;
113  unsigned int _faceTopologyOnly : 1;
114 
115  // Currently under consideration:
116  //unsigned int _childToParentMap : 1;
117  //unsigned int _ancestorFacePerFace : 1;
118  //unsigned int _computeMasks : 1;
119  };
120 
121  void refine(Options options = Options());
122 
123 public:
124  //
125  // Access to members -- some testing classes (involving vertex interpolation)
126  // currently make use of these:
127  //
134 
141 
145 
146  IndexArray const getFaceChildFaces(Index parentFace) const;
147  IndexArray const getFaceChildEdges(Index parentFace) const;
148  IndexArray const getEdgeChildEdges(Index parentEdge) const;
149 
150  // Child-to-parent relationships (not yet complete -- unclear how we will define the
151  // "type" of the parent component, e.g. vertex, edge or face):
153  int getChildFaceInParentFace(Index f) const { return _childFaceTag[f]._indexInParent; }
154 
156 
158 
159 //
160 // Non-public methods:
161 //
162 protected:
163 
164  friend class FVarRefinement;
165  friend class SparseSelector;
166 
167  friend class Far::TopologyRefiner;
169 
170 
171  IndexArray getFaceChildFaces(Index parentFace);
172  IndexArray getFaceChildEdges(Index parentFace);
173  IndexArray getEdgeChildEdges(Index parentEdge);
174 
175 protected:
176  //
177  // Tags have now been added per-component in Level, but there is additional need to tag
178  // components within Refinement -- we can't tag the parent level components for any
179  // refinement (in order to keep it const) and tags associated with children that are
180  // specific to the child-to-parent mapping may not be warranted in the child level.
181  //
182  // Parent tags are only required for sparse refinement. The main property to tag is
183  // whether a component was selected, and so a single SparseTag is used for all three
184  // component types. Tagging if a component is "transitional" is also useful. This may
185  // only be necessary for edges but is currently packed into a mask per-edge for faces,
186  // which could be deferred, in which case "transitional" could be a single bit.
187  //
188  // Child tags are part of the child-to-parent mapping, which consists of the parent
189  // component index for each child component, plus a tags for the child indicating more
190  // about its relationship to its parent, e.g. is it completely defined, what the parent
191  // component type is, what is the index of the child within its parent, etc.
192  //
193  struct SparseTag {
195 
196  unsigned char _selected : 1; // component specifically selected for refinement
197  unsigned char _transitional : 4; // adjacent to a refined component (4-bits for face)
198  };
199 
200  struct ChildTag {
201  ChildTag() { }
202 
203  unsigned char _incomplete : 1; // incomplete neighborhood to represent limit of parent
204  unsigned char _parentType : 2; // type of parent component: vertex, edge or face
205  unsigned char _indexInParent : 2; // index of child wrt parent: 0-3, or iterative if N > 4
206  };
207 
208 //
209 // Remaining methods should remain protected -- for use by subclasses...
210 //
211 protected:
212  //
213  // Methods involved in constructing the parent-to-child mapping -- when the
214  // refinement is sparse, additional methods are needed to identify the selection:
215  //
218  void printParentToChildMapping() const;
219 
220  virtual void allocateParentChildIndices() = 0;
221 
222  // Supporting method for sparse refinement:
226  void markSparseEdgeChildren();
227 
228  virtual void markSparseFaceChildren() = 0;
229 
231 
232  //
233  // Methods involved in constructing the child-to-parent mapping:
234  //
236 
237  void populateFaceParentVectors(ChildTag const initialChildTags[2][4]);
238  void populateFaceParentFromParentFaces(ChildTag const initialChildTags[2][4]);
239 
240  void populateEdgeParentVectors(ChildTag const initialChildTags[2][4]);
241  void populateEdgeParentFromParentFaces(ChildTag const initialChildTags[2][4]);
242  void populateEdgeParentFromParentEdges(ChildTag const initialChildTags[2][4]);
243 
244  void populateVertexParentVectors(ChildTag const initialChildTags[2][4]);
245  void populateVertexParentFromParentFaces(ChildTag const initialChildTags[2][4]);
246  void populateVertexParentFromParentEdges(ChildTag const initialChildTags[2][4]);
247  void populateVertexParentFromParentVertices(ChildTag const initialChildTags[2][4]);
248 
249  //
250  // Methods involved in propagating component tags from parent to child:
251  //
252  void propagateComponentTags();
253 
254  void populateFaceTagVectors();
256 
257  void populateEdgeTagVectors();
260 
265 
266  //
267  // Methods (and types) involved in subdividing the topology -- though not
268  // fully exploited, any subset of the 6 relations can be generated:
269  //
270  struct Relations {
271  unsigned int _faceVertices : 1;
272  unsigned int _faceEdges : 1;
273  unsigned int _edgeVertices : 1;
274  unsigned int _edgeFaces : 1;
275  unsigned int _vertexFaces : 1;
276  unsigned int _vertexEdges : 1;
277 
278  void setAll(bool enable) {
279  _faceVertices = enable;
280  _faceEdges = enable;
281  _edgeVertices = enable;
282  _edgeFaces = enable;
283  _vertexFaces = enable;
284  _vertexEdges = enable;
285  }
286  };
287 
288  void subdivideTopology(Relations const& relationsToSubdivide);
289 
290  virtual void populateFaceVertexRelation() = 0;
291  virtual void populateFaceEdgeRelation() = 0;
292  virtual void populateEdgeVertexRelation() = 0;
293  virtual void populateEdgeFaceRelation() = 0;
294  virtual void populateVertexFaceRelation() = 0;
295  virtual void populateVertexEdgeRelation() = 0;
296 
297  //
298  // Methods involved in subdividing and inspecting sharpness values:
299  //
301 
303  void subdivideEdgeSharpness();
305 
306  //
307  // Methods involved in subdividing face-varying topology:
308  //
309  void subdivideFVarChannels();
310 
311 protected:
312  //
313  // Data members -- the logical grouping of some of these (and methods that make use
314  // of them) may lead to grouping them into a few utility classes or structs...
315  //
316  friend class Level; // Access for some debugging information
317 
318  // Defined on construction:
319  Level const * _parent;
322 
323  // Defined by the subclass:
326 
327  // Determined by the refinement options:
328  bool _uniform;
329 
330  //
331  // Inventory and ordering of the types of child components:
332  //
333  int _childFaceFromFaceCount; // arguably redundant (all faces originate from faces)
339 
340  int _firstChildFaceFromFace; // arguably redundant (all faces originate from faces)
346 
347  //
348  // The parent-to-child mapping:
349  // These are vectors sized according to the number of parent components (and
350  // their topology) that contain references/indices to the child components that
351  // result from them by refinement. When refinement is sparse, parent components
352  // that have not spawned all child components will have their missing children
353  // marked as invalid.
354  //
355  // NOTE the "Array" members here. Often vectors within the Level can be shared
356  // with the Refinement, and an Array instance is used to do so. If not shared
357  // the subclass just initializes the Array members after allocating its own local
358  // vector members.
359  //
362 
363  IndexVector _faceChildFaceIndices; // *cannot* always use face-vert counts/offsets
364  IndexVector _faceChildEdgeIndices; // can use face-vert counts/offsets
366 
367  IndexVector _edgeChildEdgeIndices; // trivial/corresponding pair for each
369 
371 
372  //
373  // The child-to-parent mapping:
374  //
378 
379  std::vector<ChildTag> _childFaceTag;
380  std::vector<ChildTag> _childEdgeTag;
381  std::vector<ChildTag> _childVertexTag;
382 
383  //
384  // Tags for spase selection of components:
385  //
386  std::vector<SparseTag> _parentFaceTag;
387  std::vector<SparseTag> _parentEdgeTag;
388  std::vector<SparseTag> _parentVertexTag;
389 
390  //
391  // Refinement data for face-varying channels present in the Levels being refined:
392  //
393  std::vector<FVarRefinement*> _fvarChannels;
394 
395 public:
396 //#define _VTR_COMPUTE_MASK_WEIGHTS_ENABLED
397 #ifdef _VTR_COMPUTE_MASK_WEIGHTS_ENABLED
398  // TEMPORARY -- FOR ILLUSTRATIVE PURPOSES ONLY...
399  //
400  // Mask for the child vertices stored relative to parent topology, i.e. weights
401  // for a child face-vertex are stored relative to the parent face -- a weight for
402  // each of the parent face's vertices.
403  //
404  // Currently the full complement of weights is used and expected to be applied, e.g.
405  // for a crease in the interior, there may be no face-vert weights in the stencil
406  // and so no need to apply them, but we require all and so set these to zero for now.
407  // We will need some kind of stencil type associated with each child vertex if we
408  // are to avoid doing so in order to detect the difference.
409  //
410  // Note this is potentially extremely wasteful in terms of memory when the set of
411  // refined components in the child is small relative to the parent. All possible
412  // stencil weights (i.e. for uniform refinement) will be allocated here if the
413  // corresonding counts/offset of the parent are to be used.
414  //
415  void computeMaskWeights();
416 
417  std::vector<float> _faceVertWeights; // matches parent face vert counts and offsets
418  std::vector<float> _edgeVertWeights; // trivially 2 per parent edge
419  std::vector<float> _edgeFaceWeights; // matches parent edge face counts and offsets
420  std::vector<float> _vertVertWeights; // trivially 1 per parent vert
421  std::vector<float> _vertEdgeWeights; // matches parent vert edge counts and offsets
422  std::vector<float> _vertFaceWeights; // matches parent vert face counts and offsets
423 #endif
424 };
425 
426 inline IndexArray const
428 
430  _faceChildFaceCountsAndOffsets[2*parentFace]);
431 }
432 inline IndexArray
434 
436  _faceChildFaceCountsAndOffsets[2*parentFace]);
437 }
438 
439 inline IndexArray const
441 
443  _faceChildEdgeCountsAndOffsets[2*parentFace]);
444 }
445 inline IndexArray
447 
449  _faceChildEdgeCountsAndOffsets[2*parentFace]);
450 }
451 
452 inline IndexArray const
454 
455  return IndexArray(&_edgeChildEdgeIndices[parentEdge*2], 2);
456 }
457 
458 inline IndexArray
460 
461  return IndexArray(&_edgeChildEdgeIndices[parentEdge*2], 2);
462 }
463 
464 } // end namespace Vtr
465 
466 } // end namespace OPENSUBDIV_VERSION
467 using namespace OPENSUBDIV_VERSION;
468 } // end namespace OpenSubdiv
469 
470 #endif /* VTR_REFINEMENT_H */
471 
A specialized factory for feature adaptive PatchTables.
void populateFaceParentVectors(ChildTag const initialChildTags[2][4])
void populateEdgeParentFromParentFaces(ChildTag const initialChildTags[2][4])
void populateVertexParentFromParentFaces(ChildTag const initialChildTags[2][4])
void refine(Options options=Options())
Refinement(Level const &parent, Level &child, Sdc::Options const &schemeOptions)
std::vector< Index > IndexVector
Definition: types.h:70
void populateEdgeParentFromParentEdges(ChildTag const initialChildTags[2][4])
void populateVertexParentFromParentVertices(ChildTag const initialChildTags[2][4])
void populateEdgeParentVectors(ChildTag const initialChildTags[2][4])
void populateVertexParentFromParentEdges(ChildTag const initialChildTags[2][4])
Stores topology data for a specified set of refinement options.
void populateVertexParentVectors(ChildTag const initialChildTags[2][4])
IndexArray const getFaceChildFaces(Index parentFace) const
Definition: refinement.h:427
std::vector< FVarRefinement * > _fvarChannels
Definition: refinement.h:393
void populateFaceParentFromParentFaces(ChildTag const initialChildTags[2][4])
IndexArray const getEdgeChildEdges(Index parentEdge) const
Definition: refinement.h:453
void subdivideTopology(Relations const &relationsToSubdivide)
IndexArray const getFaceChildEdges(Index parentFace) const
Definition: refinement.h:440