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 OPENSUBDIV3_VTR_REFINEMENT_H
25 #define OPENSUBDIV3_VTR_REFINEMENT_H
26 
27 #include "../version.h"
28 
29 #include "../sdc/types.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 Vtr {
43 namespace internal {
44 
45 class FVarRefinement;
46 
47 //
48 //  Refinement:
49 //      A refinement is a mapping between two levels -- relating the components in the original
50 //  (parent) level to the one refined (child).  The refinement may be complete (uniform) or sparse
51 //  (adaptive or otherwise selective), so not all components in the parent level will spawn
52 //  components in the child level.
53 //
54 //  Refinement is an abstract class and expects subclasses corresponding to the different types
55 //  of topological splits that the supported subdivision schemes collectively require, i.e. those
56 //  listed in Sdc::SplitType.  Note the virtual requirements expected of the subclasses in the list
57 //  of protected methods -- they differ mainly in the topology that is created in the child Level
58 //  and not the propagation of tags through refinement, subdivision of sharpness values or the
59 //  treatment of face-varying data.  The primary subclasses are QuadRefinement and TriRefinement.
60 //
61 //  At a high level, all that is necessary in terms of interface is to construct, initialize
62 //  (linking the two levels), optionally select components for sparse refinement (via use of the
63 //  SparseSelector) and call the refine() method.  This usage is expected of Far::TopologyRefiner.
64 //
65 //  Since we really want this class to be restricted from public access eventually, all methods
66 //  begin with lower case (as is the convention for protected methods) and the list of friends
67 //  will be maintained more strictly.
68 //
69 class Refinement {
70 
71 public:
72     Refinement(Level const & parent, Level & child, Sdc::Options const& schemeOptions);
73     virtual ~Refinement();
74 
parent()75     Level const& parent() const { return *_parent; }
child()76     Level const& child() const  { return *_child; }
child()77     Level&       child()        { return *_child; }
78 
getSplitType()79     Sdc::Split getSplitType() const { return _splitType; }
getRegularFaceSize()80     int getRegularFaceSize() const { return _regFaceSize; }
getOptions()81     Sdc::Options getOptions() const { return _options; }
82 
83     //  Face-varying:
getNumFVarChannels()84     int getNumFVarChannels() const { return (int) _fvarChannels.size(); }
85 
getFVarRefinement(int c)86     FVarRefinement const & getFVarRefinement(int c) const { return *_fvarChannels[c]; }
87 
88     //
89     //  Options associated with the actual refinement operation, which may end up
90     //  quite involved if we want to allow for the refinement of data that is not
91     //  of interest to be suppressed.  For now we have:
92     //
93     //      "sparse": the alternative to uniform refinement, which requires that
94     //          components be previously selected/marked to be included.
95     //
96     //      "minimal topology": this is one that may get broken down into a finer
97     //          set of options.  It suppresses "full topology" in the child level
98     //          and only generates what is minimally necessary for interpolation --
99     //          which requires at least the face-vertices for faces, but also the
100     //          vertex-faces for any face-varying channels present.  So it will
101     //          generate one or two of the six possible topological relations.
102     //
103     //  These are strictly controlled right now, e.g. for sparse refinement, we
104     //  currently enforce full topology at the finest level to allow for subsequent
105     //  patch construction.
106     //
107     struct Options {
OptionsOptions108         Options() : _sparse(false),
109                     _faceVertsFirst(false),
110                     _minimalTopology(false)
111                     { }
112 
113         unsigned int _sparse          : 1;
114         unsigned int _faceVertsFirst  : 1;
115         unsigned int _minimalTopology : 1;
116 
117         //  Still under consideration:
118         //unsigned int _childToParentMap : 1;
119     };
120 
121     void refine(Options options = Options());
122 
hasFaceVerticesFirst()123     bool hasFaceVerticesFirst() const { return _faceVertsFirst; }
124 
125 public:
126     //
127     //  Access to members -- some testing classes (involving vertex interpolation)
128     //  currently make use of these:
129     //
getNumChildFacesFromFaces()130     int getNumChildFacesFromFaces() const       { return _childFaceFromFaceCount; }
getNumChildEdgesFromFaces()131     int getNumChildEdgesFromFaces() const       { return _childEdgeFromFaceCount; }
getNumChildEdgesFromEdges()132     int getNumChildEdgesFromEdges() const       { return _childEdgeFromEdgeCount; }
getNumChildVerticesFromFaces()133     int getNumChildVerticesFromFaces() const    { return _childVertFromFaceCount; }
getNumChildVerticesFromEdges()134     int getNumChildVerticesFromEdges() const    { return _childVertFromEdgeCount; }
getNumChildVerticesFromVertices()135     int getNumChildVerticesFromVertices() const { return _childVertFromVertCount; }
136 
getFirstChildFaceFromFaces()137     Index getFirstChildFaceFromFaces() const      { return _firstChildFaceFromFace; }
getFirstChildEdgeFromFaces()138     Index getFirstChildEdgeFromFaces() const      { return _firstChildEdgeFromFace; }
getFirstChildEdgeFromEdges()139     Index getFirstChildEdgeFromEdges() const      { return _firstChildEdgeFromEdge; }
getFirstChildVertexFromFaces()140     Index getFirstChildVertexFromFaces() const    { return _firstChildVertFromFace; }
getFirstChildVertexFromEdges()141     Index getFirstChildVertexFromEdges() const    { return _firstChildVertFromEdge; }
getFirstChildVertexFromVertices()142     Index getFirstChildVertexFromVertices() const { return _firstChildVertFromVert; }
143 
getFaceChildVertex(Index f)144     Index getFaceChildVertex(Index f) const   { return _faceChildVertIndex[f]; }
getEdgeChildVertex(Index e)145     Index getEdgeChildVertex(Index e) const   { return _edgeChildVertIndex[e]; }
getVertexChildVertex(Index v)146     Index getVertexChildVertex(Index v) const { return _vertChildVertIndex[v]; }
147 
148     ConstIndexArray  getFaceChildFaces(Index parentFace) const;
149     ConstIndexArray  getFaceChildEdges(Index parentFace) const;
150     ConstIndexArray  getEdgeChildEdges(Index parentEdge) const;
151 
152     //  Child-to-parent relationships
isChildVertexComplete(Index v)153     bool isChildVertexComplete(Index v) const       { return ! _childVertexTag[v]._incomplete; }
154 
getChildFaceParentFace(Index f)155     Index getChildFaceParentFace(Index f) const     { return _childFaceParentIndex[f]; }
getChildFaceInParentFace(Index f)156     int   getChildFaceInParentFace(Index f) const   { return _childFaceTag[f]._indexInParent; }
157 
getChildEdgeParentIndex(Index e)158     Index getChildEdgeParentIndex(Index e) const    { return _childEdgeParentIndex[e]; }
159 
getChildVertexParentIndex(Index v)160     Index getChildVertexParentIndex(Index v) const  { return _childVertexParentIndex[v]; }
161 
162 //
163 //  Modifiers intended for internal/protected use:
164 //
165 public:
166 
167     IndexArray getFaceChildFaces(Index parentFace);
168     IndexArray getFaceChildEdges(Index parentFace);
169     IndexArray getEdgeChildEdges(Index parentEdge);
170 
171 public:
172     //
173     //  Tags have now been added per-component in Level, but there is additional need to tag
174     //  components within Refinement -- we can't tag the parent level components for any
175     //  refinement (in order to keep it const) and tags associated with children that are
176     //  specific to the child-to-parent mapping may not be warranted in the child level.
177     //
178     //  Parent tags are only required for sparse refinement.  The main property to tag is
179     //  whether a component was selected, and so a single SparseTag is used for all three
180     //  component types.  Tagging if a component is "transitional" is also useful.  This may
181     //  only be necessary for edges but is currently packed into a mask per-edge for faces,
182     //  which could be deferred, in which case "transitional" could be a single bit.
183     //
184     //  Child tags are part of the child-to-parent mapping, which consists of the parent
185     //  component index for each child component, plus a tag for the child indicating more
186     //  about its relationship to its parent, e.g. is it completely defined, what the parent
187     //  component type is, what is the index of the child within its parent, etc.
188     //
189     struct SparseTag {
SparseTagSparseTag190         SparseTag() : _selected(0), _transitional(0) { }
191 
192         unsigned char _selected     : 1;  // component specifically selected for refinement
193         unsigned char _transitional : 4;  // adjacent to a refined component (4-bits for face)
194     };
195 
196     struct ChildTag {
ChildTagChildTag197         ChildTag() { }
198 
199         unsigned char _incomplete    : 1;  // incomplete neighborhood to represent limit of parent
200         unsigned char _parentType    : 2;  // type of parent component:  vertex, edge or face
201         unsigned char _indexInParent : 2;  // index of child wrt parent:  0-3, or iterative if N > 4
202     };
203 
204     //  Methods to access and modify tags:
getParentFaceSparseTag(Index f)205     SparseTag const & getParentFaceSparseTag(  Index f) const { return _parentFaceTag[f]; }
getParentEdgeSparseTag(Index e)206     SparseTag const & getParentEdgeSparseTag(  Index e) const { return _parentEdgeTag[e]; }
getParentVertexSparseTag(Index v)207     SparseTag const & getParentVertexSparseTag(Index v) const { return _parentVertexTag[v]; }
208 
getParentFaceSparseTag(Index f)209     SparseTag & getParentFaceSparseTag(  Index f) { return _parentFaceTag[f]; }
getParentEdgeSparseTag(Index e)210     SparseTag & getParentEdgeSparseTag(  Index e) { return _parentEdgeTag[e]; }
getParentVertexSparseTag(Index v)211     SparseTag & getParentVertexSparseTag(Index v) { return _parentVertexTag[v]; }
212 
getChildFaceTag(Index f)213     ChildTag const & getChildFaceTag(  Index f) const { return _childFaceTag[f]; }
getChildEdgeTag(Index e)214     ChildTag const & getChildEdgeTag(  Index e) const { return _childEdgeTag[e]; }
getChildVertexTag(Index v)215     ChildTag const & getChildVertexTag(Index v) const { return _childVertexTag[v]; }
216 
getChildFaceTag(Index f)217     ChildTag & getChildFaceTag(  Index f) { return _childFaceTag[f]; }
getChildEdgeTag(Index e)218     ChildTag & getChildEdgeTag(  Index e) { return _childEdgeTag[e]; }
getChildVertexTag(Index v)219     ChildTag & getChildVertexTag(Index v) { return _childVertexTag[v]; }
220 
221 //  Remaining methods should really be protected -- for use by subclasses...
222 public:
223     //
224     //  Methods involved in constructing the parent-to-child mapping -- when the
225     //  refinement is sparse, additional methods are needed to identify the selection:
226     //
227     void populateParentToChildMapping();
228     void populateParentChildIndices();
229     void printParentToChildMapping() const;
230 
231     virtual void allocateParentChildIndices() = 0;
232 
233     //  Supporting method for sparse refinement:
234     void initializeSparseSelectionTags();
235     void markSparseChildComponentIndices();
236     void markSparseVertexChildren();
237     void markSparseEdgeChildren();
238 
239     virtual void markSparseFaceChildren() = 0;
240 
241     void initializeChildComponentCounts();
242 
243     //
244     //  Methods involved in constructing the child-to-parent mapping:
245     //
246     void populateChildToParentMapping();
247 
248     void populateFaceParentVectors(ChildTag const initialChildTags[2][4]);
249     void populateFaceParentFromParentFaces(ChildTag const initialChildTags[2][4]);
250 
251     void populateEdgeParentVectors(ChildTag const initialChildTags[2][4]);
252     void populateEdgeParentFromParentFaces(ChildTag const initialChildTags[2][4]);
253     void populateEdgeParentFromParentEdges(ChildTag const initialChildTags[2][4]);
254 
255     void populateVertexParentVectors(ChildTag const initialChildTags[2][4]);
256     void populateVertexParentFromParentFaces(ChildTag const initialChildTags[2][4]);
257     void populateVertexParentFromParentEdges(ChildTag const initialChildTags[2][4]);
258     void populateVertexParentFromParentVertices(ChildTag const initialChildTags[2][4]);
259 
260     //
261     //  Methods involved in propagating component tags from parent to child:
262     //
263     void propagateComponentTags();
264 
265     void populateFaceTagVectors();
266     void populateFaceTagsFromParentFaces();
267 
268     void populateEdgeTagVectors();
269     void populateEdgeTagsFromParentFaces();
270     void populateEdgeTagsFromParentEdges();
271 
272     void populateVertexTagVectors();
273     void populateVertexTagsFromParentFaces();
274     void populateVertexTagsFromParentEdges();
275     void populateVertexTagsFromParentVertices();
276 
277     //
278     //  Methods (and types) involved in subdividing the topology -- though not
279     //  fully exploited, any subset of the 6 relations can be generated:
280     //
281     struct Relations {
282         unsigned int   _faceVertices : 1;
283         unsigned int   _faceEdges    : 1;
284         unsigned int   _edgeVertices : 1;
285         unsigned int   _edgeFaces    : 1;
286         unsigned int   _vertexFaces  : 1;
287         unsigned int   _vertexEdges  : 1;
288 
setAllRelations289         void setAll(bool enable) {
290             _faceVertices = enable;
291             _faceEdges    = enable;
292             _edgeVertices = enable;
293             _edgeFaces    = enable;
294             _vertexFaces  = enable;
295             _vertexEdges  = enable;
296         }
297     };
298 
299     void subdivideTopology(Relations const& relationsToSubdivide);
300 
301     virtual void populateFaceVertexRelation() = 0;
302     virtual void populateFaceEdgeRelation() = 0;
303     virtual void populateEdgeVertexRelation() = 0;
304     virtual void populateEdgeFaceRelation() = 0;
305     virtual void populateVertexFaceRelation() = 0;
306     virtual void populateVertexEdgeRelation() = 0;
307 
308     //
309     //  Methods involved in subdividing and inspecting sharpness values:
310     //
311     void subdivideSharpnessValues();
312 
313     void subdivideVertexSharpness();
314     void subdivideEdgeSharpness();
315     void reclassifySemisharpVertices();
316 
317     //
318     //  Methods involved in subdividing face-varying topology:
319     //
320     void subdivideFVarChannels();
321 
322 protected:
323     // A debug method of Level prints a Refinement (should really change this)
324     friend void Level::print(const Refinement *) const;
325 
326     //
327     //  Data members -- the logical grouping of some of these (and methods that make use
328     //  of them) may lead to grouping them into a few utility classes or structs...
329     //
330 
331     //  Defined on construction:
332     Level const * _parent;
333     Level *       _child;
334     Sdc::Options  _options;
335 
336     //  Defined by the subclass:
337     Sdc::Split _splitType;
338     int        _regFaceSize;
339 
340     //  Determined by the refinement options:
341     bool _uniform;
342     bool _faceVertsFirst;
343 
344     //
345     //  Inventory and ordering of the types of child components:
346     //
347     int _childFaceFromFaceCount;  // arguably redundant (all faces originate from faces)
348     int _childEdgeFromFaceCount;
349     int _childEdgeFromEdgeCount;
350     int _childVertFromFaceCount;
351     int _childVertFromEdgeCount;
352     int _childVertFromVertCount;
353 
354     int _firstChildFaceFromFace;  // arguably redundant (all faces originate from faces)
355     int _firstChildEdgeFromFace;
356     int _firstChildEdgeFromEdge;
357     int _firstChildVertFromFace;
358     int _firstChildVertFromEdge;
359     int _firstChildVertFromVert;
360 
361     //
362     //  The parent-to-child mapping:
363     //      These are vectors sized according to the number of parent components (and
364     //  their topology) that contain references/indices to the child components that
365     //  result from them by refinement.  When refinement is sparse, parent components
366     //  that have not spawned all child components will have their missing children
367     //  marked as invalid.
368     //
369     //  NOTE the "Array" members here.  Often vectors within the Level can be shared
370     //  with the Refinement, and an Array instance is used to do so.  If not shared
371     //  the subclass just initializes the Array members after allocating its own local
372     //  vector members.
373     //
374     IndexArray _faceChildFaceCountsAndOffsets;
375     IndexArray _faceChildEdgeCountsAndOffsets;
376 
377     IndexVector _faceChildFaceIndices;  // *cannot* always use face-vert counts/offsets
378     IndexVector _faceChildEdgeIndices;  // can use face-vert counts/offsets
379     IndexVector _faceChildVertIndex;
380 
381     IndexVector _edgeChildEdgeIndices;  // trivial/corresponding pair for each
382     IndexVector _edgeChildVertIndex;
383 
384     IndexVector _vertChildVertIndex;
385 
386     //
387     //  The child-to-parent mapping:
388     //
389     IndexVector _childFaceParentIndex;
390     IndexVector _childEdgeParentIndex;
391     IndexVector _childVertexParentIndex;
392 
393     std::vector<ChildTag> _childFaceTag;
394     std::vector<ChildTag> _childEdgeTag;
395     std::vector<ChildTag> _childVertexTag;
396 
397     //
398     //  Tags for sparse selection of components:
399     //
400     std::vector<SparseTag> _parentFaceTag;
401     std::vector<SparseTag> _parentEdgeTag;
402     std::vector<SparseTag> _parentVertexTag;
403 
404     //
405     //  Refinement data for face-varying channels present in the Levels being refined:
406     //
407     std::vector<FVarRefinement*> _fvarChannels;
408 };
409 
410 inline ConstIndexArray
getFaceChildFaces(Index parentFace)411 Refinement::getFaceChildFaces(Index parentFace) const {
412 
413     return ConstIndexArray(&_faceChildFaceIndices[_faceChildFaceCountsAndOffsets[2*parentFace+1]],
414                                              _faceChildFaceCountsAndOffsets[2*parentFace]);
415 }
416 
417 inline IndexArray
getFaceChildFaces(Index parentFace)418 Refinement::getFaceChildFaces(Index parentFace) {
419 
420     return IndexArray(&_faceChildFaceIndices[_faceChildFaceCountsAndOffsets[2*parentFace+1]],
421                                              _faceChildFaceCountsAndOffsets[2*parentFace]);
422 }
423 
424 inline ConstIndexArray
getFaceChildEdges(Index parentFace)425 Refinement::getFaceChildEdges(Index parentFace) const {
426 
427     return ConstIndexArray(&_faceChildEdgeIndices[_faceChildEdgeCountsAndOffsets[2*parentFace+1]],
428                                              _faceChildEdgeCountsAndOffsets[2*parentFace]);
429 }
430 inline IndexArray
getFaceChildEdges(Index parentFace)431 Refinement::getFaceChildEdges(Index parentFace) {
432 
433     return IndexArray(&_faceChildEdgeIndices[_faceChildEdgeCountsAndOffsets[2*parentFace+1]],
434                                              _faceChildEdgeCountsAndOffsets[2*parentFace]);
435 }
436 
437 inline ConstIndexArray
getEdgeChildEdges(Index parentEdge)438 Refinement::getEdgeChildEdges(Index parentEdge) const {
439 
440     return ConstIndexArray(&_edgeChildEdgeIndices[parentEdge*2], 2);
441 }
442 
443 inline IndexArray
getEdgeChildEdges(Index parentEdge)444 Refinement::getEdgeChildEdges(Index parentEdge) {
445 
446     return IndexArray(&_edgeChildEdgeIndices[parentEdge*2], 2);
447 }
448 
449 } // end namespace internal
450 } // end namespace Vtr
451 
452 } // end namespace OPENSUBDIV_VERSION
453 using namespace OPENSUBDIV_VERSION;
454 } // end namespace OpenSubdiv
455 
456 #endif /* OPENSUBDIV3_VTR_REFINEMENT_H */
457