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