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