All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
topologyRefinerFactory.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 FAR_TOPOLOGY_REFINER_FACTORY_H
25 #define FAR_TOPOLOGY_REFINER_FACTORY_H
26 
27 #include "../version.h"
28 
29 #include "../far/topologyRefiner.h"
30 
31 #include <cassert>
32 
33 namespace OpenSubdiv {
34 namespace OPENSUBDIV_VERSION {
35 
36 namespace Far {
37 
38 //
39 // TopologyRefinerFactoryBase:
40 // This is an abstract base class for subclasses that are intended to construct
41 // TopologyRefiner from a mesh class that defines the subclass. The subclasses are
42 // parameterized by the mesh type <class MESH>. The base class provides all
43 // implementation details related to assembly and validation that are independent
44 // of the subclass' mesh type.
45 //
46 // Its still unclear where the division of functionality lies between construction
47 // of the Factory and creation of an instance of the Tables. We definitely do not
48 // want data generation in the construction to require duplication or copying in
49 // the creation. Overloading Create() to "close" the tables (copying the base level
50 // and other data, but refining differently) are also possibilities.
51 //
52 // The subdiv type/options are specified on construction of the factory and are passed
53 // on to each instance of TopologyRefiner that it creates. They can be modified as
54 // there is nothing in the Factory tied to these properties. Consider overloading
55 // the Create() method (defined by subclasses) to vary these if greater flexibility
56 // per instance is desired.
57 //
59 
60 public:
61 
65 
67  numFaces;
68 
69  int const * vertsPerFace,
70  * vertIndices;
71 
74  float const * creaseWeights;
75 
77  int const * cornerVertexIndices;
78  float const * cornerWeights;
79 
80  // Face-varying data channel -- value indices correspond to vertex indices,
81  // i.e. one for every vertex of every face:
82  //
83  struct FVarChannel {
84 
85  int numValues;
86  int const * valueIndices;
87 
89  };
90 
93 
95  };
96 
97 protected:
98 
102 
104 };
105 
106 
107 //
108 // TopologyRefinerFactory<MESH>:
109 // The factory class template to convert and refine an instance of TopologyRefiner
110 // from an arbitrary mesh class. While a class template, the implementation is not
111 // (cannot) be complete, so specialization of a few methods is required.
112 // This template provides both the interface and high level assembly for the
113 // construction of the TopologyRefiner instance. The high level construction executes
114 // a specific set of operations to convert the client's MESH into TopologyRefiner,
115 // using methods independent of MESH from the base class and those specialized for
116 // class MESH appropriately.
117 //
118 template <class MESH>
120 
121 public:
122 
125 
128 
145  static TopologyRefiner* Create(Sdc::Type type, Sdc::Options options, MESH const& mesh);
146 
147 protected:
148  //
149  // Methods to be specialized that implement all details specific to class MESH required
150  // to convert MESH data to TopologyRefiner. Note that some of these *must* be specialized
151  // in order to complete construction.
152  //
153  // There are two minimal construction requirements and one optional.
154  //
155  // See the comments in the generic stubs for details on how to write these.
156  //
157  // Required:
158  static void resizeComponentTopology(TopologyRefiner& refiner, MESH const& mesh);
159  static void assignComponentTopology(TopologyRefiner& refiner, MESH const& mesh);
160 
161  // Optional:
162  static void assignFaceVaryingTopology(TopologyRefiner& refiner, MESH const& mesh);
163  static void assignComponentTags(TopologyRefiner& refiner, MESH const& mesh);
164 
165 protected:
166 
167  // Other protected details -- not to be specialized:
168  static void populateBaseLevel(TopologyRefiner& refiner, MESH const& mesh);
169 };
170 
171 
172 //
173 // Generic implementations:
174 //
175 template <class MESH>
176 TopologyRefiner*
178 
179  TopologyRefiner *refiner = new TopologyRefiner(type, options);
180 
181  populateBaseLevel(*refiner, mesh);
182 
183  return refiner;
184 }
185 
186 template <class MESH>
187 void
189 
190  //
191  // The following three methods may end up virtual:
192  // - resize the component counts and relation counts for individual components:
193  // - assign the topological relations for all components:
194  // - assign any sharpness values, hole tags, etc:
195  // Note that we can do some sanity checking (independent of the type MESH) between these
196  // to ensure that a client has done what is necessary at each stage.
197  //
198 
199  // Required specialization for MESH:
200  resizeComponentTopology(refiner, mesh);
201 
202  validateComponentTopologySizing(refiner);
203 
204  // Required specialization for MESH:
205  assignComponentTopology(refiner, mesh);
206  validateVertexComponentTopologyAssignment(refiner);
207 
208  // Optional specialization for MESH:
209  assignComponentTags(refiner, mesh);
210 
211  // Finalize the translation of the mesh after its full specification above:
212  applyComponentTagsAndBoundarySharpness(refiner);
213 
214  // Optional specialization for MESH:
215  assignFaceVaryingTopology(refiner, mesh);
216  validateFaceVaryingComponentTopologyAssignment(refiner);
217 }
218 
219 // XXXX manuelk MSVC specializes these templated functions which creates duplicated symbols
220 #ifndef _MSC_VER
221 
222 template <class MESH>
223 void
225 
226  assert("Missing specialization for TopologyRefinerFactory<MESH>::resizeComponentTopology()" == 0);
227 
228  //
229  // Sizing the topology tables:
230  // This method is for determining the sizes of the various topology tables (and other
231  // data) associated with the mesh. Once completed, appropriate memory will be allocated
232  // and an additional method invoked to populate it accordingly.
233  //
234  // The following methods should be called -- first those to specify the number of faces,
235  // edges and vertices in the mesh:
236  //
237  // void TopologyRefiner::setBaseFaceCount(int count)
238  // void TopologyRefiner::setBaseEdgeCount(int count)
239  // void TopologyRefiner::setBaseVertexCount(int count)
240  //
241  // and then for each face, edge and vertex, the number of its incident components:
242  //
243  // void TopologyRefiner::setBaseFaceVertexCount(Index face, int count)
244  // void TopologyRefiner::setBaseEdgeFaceCount( Index edge, int count)
245  // void TopologyRefiner::setBaseVertexFaceCount(Index vertex, int count)
246  // void TopologyRefiner::setBaseVertexEdgeCount(Index vertex, int count)
247  //
248  // The count/size for a component type must be set before indices associated with that
249  // component type can be used.
250  //
251  // Note that it is only necessary to size 4 of the 6 supported topological relations --
252  // the number of edge-vertices is fixed at two per edge, and the number of face-edges is
253  // the same as the number of face-vertices.
254  //
255  // So a single pass through your mesh to gather up all of this sizing information will
256  // allow the Tables to be allocated appropriately once and avoid any dynamic resizing as
257  // it grows.
258  //
259 }
260 
261 template <class MESH>
262 void
264 
265  assert("Missing specialization for TopologyRefinerFactory<MESH>::assignComponentTopology()" == 0);
266 
267  //
268  // Assigning the topology tables:
269  // Once the topology tables have been allocated, the six required topological
270  // relations can be directly populated using the following methods:
271  //
272  // void IndexArray TopologyRefiner::baseFaceVertices(Index face)
273  // void IndexArray TopologyRefiner::baseFaceEdges(Index face)
274  //
275  // void IndexArray TopologyRefiner::baseEdgeVertices(Index edge)
276  // void IndexArray TopologyRefiner::baseEdgeFaces(Index edge)
277  //
278  // void IndexArray TopologyRefiner::baseVertexEdges(Index vertex)
279  // void IndexArray TopologyRefiner::baseVertexFaces(Index vertex)
280  //
281  // For the last two relations -- the faces and edges incident a vertex -- there are
282  // also "local indices" that must be specified (considering doing this internally),
283  // where the "local index" of each incident face or edge is the index of the vertex
284  // within that face or edge, and so ranging from 0-3 for incident quads and 0-1 for
285  // incident edges. These are assigned through similarly retrieved arrays:
286  //
287  // LocalIndexArray TopologyRefiner::baseVertexFaceLocalIndices(Index vertex)
288  // LocalIndexArray TopologyRefiner::baseVertexEdgeLocalIndices(Index vertex)
289  //
290  // As noted, we are considering determining these internally to avoid this complexity,
291  // but that will require iteration through the sets of vertex-faces and edges to find
292  // the location of the vertex within each. If that is known at the time the incident
293  // componets are assigned, they we can avoid that separate pass.
294  //
295  // We also need to tag vertices as manifold or not here. Failure to do so explicitly
296  // will require the factory analyze the local neighborhood of each component, which
297  // is costly and often unnecessary.
298  //
299 }
300 
301 template <class MESH>
302 void
304 
305  //
306  // Optional assigning face-varying topology tables:
307  //
308  // Create independent face-varying primitive variable channels:
309  // int TopologyRefiner::createFVarChannel(int numValues)
310  //
311  // For each channel, populate the face-vertex values:
312  // IndexArray TopologyRefiner::getBaseFVarFaceValues(Index face, int channel = 0)
313  //
314 }
315 
316 template <class MESH>
317 void
319 
320  //
321  // Optional tagging:
322  // This is where any additional feature tags -- sharpness, holes, etc. -- can be
323  // specified. For now, this is limited to sharpness using the following:
324  //
325  // float& TopologyRefiner::baseEdgeSharpness(Index edge)
326  // float& TopologyRefiner::baseVertexSharpness(Index vertex)
327  //
328  // which can be used on the LHS of assignments.
329  //
330  // Tagging holes will become available in the near future as sets of bitfields for
331  // each component type are introduced and propogated through the refinement hierarchy.
332  //
333 }
334 
335 #endif
336 
337 } // end namespace Far
338 
339 } // end namespace OPENSUBDIV_VERSION
340 using namespace OPENSUBDIV_VERSION;
341 } // end namespace OpenSubdiv
342 
343 #endif /* FAR_TOPOLOGY_REFINER_FACTORY_H */
344 
static void assignFaceVaryingTopology(TopologyRefiner &refiner, MESH const &mesh)
static void applyComponentTagsAndBoundarySharpness(TopologyRefiner &refiner)
static void assignComponentTags(TopologyRefiner &refiner, MESH const &mesh)
static TopologyRefiner * Create(Sdc::Type type, Sdc::Options options, MESH const &mesh)
Instantiates TopologyRefiner from client-provided topological representation.
static void validateVertexComponentTopologyAssignment(TopologyRefiner &refiner)
static void validateFaceVaryingComponentTopologyAssignment(TopologyRefiner &refiner)
static void assignComponentTopology(TopologyRefiner &refiner, MESH const &mesh)
static void resizeComponentTopology(TopologyRefiner &refiner, MESH const &mesh)
static void validateComponentTopologySizing(TopologyRefiner &refiner)
Stores topology data for a specified set of refinement options.
static void populateBaseLevel(TopologyRefiner &refiner, MESH const &mesh)