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_FAR_TOPOLOGY_REFINER_H
25 #define OPENSUBDIV3_FAR_TOPOLOGY_REFINER_H
26 
27 #include "../version.h"
28 
29 #include "../sdc/types.h"
30 #include "../sdc/options.h"
31 #include "../far/types.h"
32 #include "../far/topologyLevel.h"
33 
34 #include <vector>
35 
36 
37 namespace OpenSubdiv {
38 namespace OPENSUBDIV_VERSION {
39 
40 namespace Vtr { namespace internal { class SparseSelector; } }
41 namespace Far { namespace internal { class FeatureMask; } }
42 
43 namespace Far {
44 
45 template <typename REAL> class PrimvarRefinerReal;
46 template <class MESH> class TopologyRefinerFactory;
47 
48 ///
49 ///  \brief Stores topology data for a specified set of refinement options.
50 ///
51 class TopologyRefiner {
52 
53 public:
54 
55     /// \brief Constructor
56     TopologyRefiner(Sdc::SchemeType type, Sdc::Options options = Sdc::Options());
57 
58     /// \brief Destructor
59     ~TopologyRefiner();
60 
61     /// \brief Returns the subdivision scheme
GetSchemeType()62     Sdc::SchemeType GetSchemeType() const    { return _subdivType; }
63 
64     /// \brief Returns the subdivision options
GetSchemeOptions()65     Sdc::Options GetSchemeOptions() const { return _subdivOptions; }
66 
67     /// \brief Returns true if uniform refinement has been applied
IsUniform()68     bool IsUniform() const   { return _isUniform; }
69 
70     /// \brief Returns the number of refinement levels
GetNumLevels()71     int  GetNumLevels() const { return (int)_farLevels.size(); }
72 
73     /// \brief Returns the highest level of refinement
GetMaxLevel()74     int  GetMaxLevel() const { return _maxLevel; }
75 
76     /// \brief Returns the maximum vertex valence in all levels
GetMaxValence()77     int  GetMaxValence() const { return _maxValence; }
78 
79     /// \brief Returns true if faces have been tagged as holes
HasHoles()80     bool HasHoles() const { return _hasHoles; }
81 
82     /// \brief Returns the total number of vertices in all levels
GetNumVerticesTotal()83     int GetNumVerticesTotal() const { return _totalVertices; }
84 
85     /// \brief Returns the total number of edges in all levels
GetNumEdgesTotal()86     int GetNumEdgesTotal() const { return _totalEdges; }
87 
88     /// \brief Returns the total number of edges in all levels
GetNumFacesTotal()89     int GetNumFacesTotal() const { return _totalFaces; }
90 
91     /// \brief Returns the total number of face vertices in all levels
GetNumFaceVerticesTotal()92     int GetNumFaceVerticesTotal() const { return _totalFaceVertices; }
93 
94     /// \brief Returns a handle to access data specific to a particular level
GetLevel(int level)95     TopologyLevel const & GetLevel(int level) const { return _farLevels[level]; }
96 
97     //@{
98     ///  @name High-level refinement and related methods
99     ///
100 
101     //
102     // Uniform refinement
103     //
104 
105     /// \brief Uniform refinement options
106     ///
107     /// Options for uniform refinement, including the number of levels, vertex
108     /// ordering and generation of topology information.
109     ///
110     /// Note the impact of the option to generate fullTopologyInLastLevel.  Given
111     /// subsequent levels of uniform refinement typically reguire 4x the data
112     /// of the previous level, only the minimum amount of data is generated in the
113     /// last level by default, i.e. a vertex and face-vertex list.  If requiring
114     /// topology traversal of the last level, e.g. inspecting edges or incident
115     /// faces of vertices, the option to generate full topology in the last
116     /// level should be enabled.
117     ///
118     struct UniformOptions {
119 
UniformOptionsUniformOptions120         UniformOptions(int level) :
121             refinementLevel(level),
122             orderVerticesFromFacesFirst(false),
123             fullTopologyInLastLevel(false) { }
124 
125         unsigned int refinementLevel:4,             ///< Number of refinement iterations
126                      orderVerticesFromFacesFirst:1, ///< Order child vertices from faces first
127                                                     ///< instead of child vertices of vertices
128                      fullTopologyInLastLevel:1;     ///< Skip topological relationships in the last
129                                                     ///< level of refinement that are not needed for
130                                                     ///< interpolation (keep false if using limit).
131     };
132 
133     /// \brief Refine the topology uniformly
134     ///
135     /// This method applies uniform refinement to the level specified in the
136     /// given UniformOptions.
137     ///
138     /// Note the impact of the UniformOption to generate fullTopologyInLastLevel
139     /// and be sure it is assigned to satisfy the needs of the resulting refinement.
140     ///
141     /// @param options   Options controlling uniform refinement
142     ///
143     void RefineUniform(UniformOptions options);
144 
145     /// \brief Returns the options specified on refinement
GetUniformOptions()146     UniformOptions GetUniformOptions() const { return _uniformOptions; }
147 
148     //
149     // Adaptive refinement
150     //
151 
152     /// \brief Adaptive refinement options
153     struct AdaptiveOptions {
154 
AdaptiveOptionsAdaptiveOptions155         AdaptiveOptions(int level) :
156             isolationLevel(level),
157             secondaryLevel(15),
158             useSingleCreasePatch(false),
159             useInfSharpPatch(false),
160             considerFVarChannels(false),
161             orderVerticesFromFacesFirst(false) { }
162 
163         unsigned int isolationLevel:4;              ///< Number of iterations applied to isolate
164                                                     ///< extraordinary vertices and creases
165         unsigned int secondaryLevel:4;              ///< Shallower level to stop isolation of
166                                                     ///< smooth irregular features
167         unsigned int useSingleCreasePatch:1;        ///< Use 'single-crease' patch and stop
168                                                     ///< isolation where applicable
169         unsigned int useInfSharpPatch:1;            ///< Use infinitely sharp patches and stop
170                                                     ///< isolation where applicable
171         unsigned int considerFVarChannels:1;        ///< Inspect face-varying channels and
172                                                     ///< isolate when irregular features present
173         unsigned int orderVerticesFromFacesFirst:1; ///< Order child vertices from faces first
174                                                     ///< instead of child vertices of vertices
175     };
176 
177     /// \brief Feature Adaptive topology refinement
178     ///
179     /// @param options         Options controlling adaptive refinement
180     ///
181     /// @param selectedFaces   Limit adaptive refinement to the specified faces
182     ///
183     void RefineAdaptive(AdaptiveOptions options,
184                         ConstIndexArray selectedFaces = ConstIndexArray());
185 
186     /// \brief Returns the options specified on refinement
GetAdaptiveOptions()187     AdaptiveOptions GetAdaptiveOptions() const { return _adaptiveOptions; }
188 
189     /// \brief Unrefine the topology, keeping only the base level.
190     void Unrefine();
191 
192 
193     //@{
194     /// @name Number and properties of face-varying channels:
195     ///
196 
197     /// \brief Returns the number of face-varying channels in the tables
198     int GetNumFVarChannels() const;
199 
200     /// \brief Returns the face-varying interpolation rule set for a given channel
201     Sdc::Options::FVarLinearInterpolation GetFVarLinearInterpolation(int channel = 0) const;
202 
203     /// \brief Returns the total number of face-varying values in all levels
204     int GetNumFVarValuesTotal(int channel = 0) const;
205 
206     //@}
207 
208 protected:
209 
210     //
211     //  Lower level protected methods intended strictly for internal use:
212     //
213     template <class MESH>
214     friend class TopologyRefinerFactory;
215     friend class TopologyRefinerFactoryBase;
216     friend class PatchTableBuilder;
217     friend class PatchBuilder;
218     friend class PtexIndices;
219     template <typename REAL>
220     friend class PrimvarRefinerReal;
221 
222     //  Copy constructor exposed via the factory class:
223     TopologyRefiner(TopologyRefiner const & source);
224 
getLevel(int l)225     Vtr::internal::Level & getLevel(int l) { return *_levels[l]; }
getLevel(int l)226     Vtr::internal::Level const & getLevel(int l) const { return *_levels[l]; }
227 
getRefinement(int l)228     Vtr::internal::Refinement & getRefinement(int l) { return *_refinements[l]; }
getRefinement(int l)229     Vtr::internal::Refinement const & getRefinement(int l) const { return *_refinements[l]; }
230 
231 private:
232     //  Not default constructible or copyable:
TopologyRefiner()233     TopologyRefiner() : _uniformOptions(0), _adaptiveOptions(0) { }
234     TopologyRefiner & operator=(TopologyRefiner const &) { return *this; }
235 
236     void selectFeatureAdaptiveComponents(Vtr::internal::SparseSelector& selector,
237                                          internal::FeatureMask const & mask,
238                                          ConstIndexArray selectedFaces);
239     void selectLinearIrregularFaces(Vtr::internal::SparseSelector& selector,
240                                     ConstIndexArray selectedFaces);
241 
242     void initializeInventory();
243     void updateInventory(Vtr::internal::Level const & newLevel);
244 
245     void appendLevel(Vtr::internal::Level & newLevel);
246     void appendRefinement(Vtr::internal::Refinement & newRefinement);
247     void assembleFarLevels();
248 
249 private:
250 
251     Sdc::SchemeType _subdivType;
252     Sdc::Options    _subdivOptions;
253 
254     unsigned int _isUniform     : 1;
255     unsigned int _hasHoles      : 1;
256     unsigned int _hasIrregFaces : 1;
257     unsigned int _regFaceSize   : 3;
258     unsigned int _maxLevel      : 4;
259 
260     //  Options assigned on refinement:
261     UniformOptions  _uniformOptions;
262     AdaptiveOptions _adaptiveOptions;
263 
264     //  Cumulative properties of all levels:
265     int _totalVertices;
266     int _totalEdges;
267     int _totalFaces;
268     int _totalFaceVertices;
269     int _maxValence;
270 
271     //  Note the base level may be shared with another instance
272     bool _baseLevelOwned;
273 
274     std::vector<Vtr::internal::Level *>      _levels;
275     std::vector<Vtr::internal::Refinement *> _refinements;
276 
277     std::vector<TopologyLevel> _farLevels;
278 };
279 
280 
281 inline int
GetNumFVarChannels()282 TopologyRefiner::GetNumFVarChannels() const {
283 
284     return _levels[0]->getNumFVarChannels();
285 }
286 inline Sdc::Options::FVarLinearInterpolation
GetFVarLinearInterpolation(int channel)287 TopologyRefiner::GetFVarLinearInterpolation(int channel) const {
288 
289     return _levels[0]->getFVarOptions(channel).GetFVarLinearInterpolation();
290 }
291 
292 } // end namespace Far
293 
294 } // end namespace OPENSUBDIV_VERSION
295 using namespace OPENSUBDIV_VERSION;
296 } // end namespace OpenSubdiv
297 
298 #endif /* OPENSUBDIV3_FAR_TOPOLOGY_REFINER_H */
299