OpenSubdiv
surfaceFactory.h
Go to the documentation of this file.
1 //
2 // Copyright 2021 Pixar
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 
25 #ifndef OPENSUBDIV3_BFR_SURFACE_FACTORY_H
26 #define OPENSUBDIV3_BFR_SURFACE_FACTORY_H
27 
28 #include "../version.h"
29 
30 #include "../bfr/surface.h"
31 #include "../bfr/surfaceFactoryMeshAdapter.h"
32 #include "../sdc/options.h"
33 #include "../sdc/types.h"
34 
35 #include <cstdint>
36 
37 namespace OpenSubdiv {
38 namespace OPENSUBDIV_VERSION {
39 
40 namespace Bfr {
41 
42 //
43 // Forward declarations of public and internal classes used by factories:
44 //
45 class SurfaceFactoryCache;
46 class FaceTopology;
47 class FaceSurface;
48 
104 public:
116  class Options {
117  public:
118  Options() : _dfltFVarID(-1), _externCache(0), _enableCache(true),
119  _approxLevelSmooth(2), _approxLevelSharp(6) { }
120 
125  FVarID GetDefaultFVarID() const { return _dfltFVarID; }
126 
128  Options & EnableCaching(bool on);
130  bool IsCachingEnabled() const { return _enableCache; }
131 
135  SurfaceFactoryCache * GetExternalCache() const { return _externCache; }
136 
137  // Set refinement levels used to approximate the limit surface
138  // for smooth and sharp features (reasonable defaults assigned):
140  Options & SetApproxLevelSmooth(int level);
142  int GetApproxLevelSmooth() const { return _approxLevelSmooth; }
143 
145  Options & SetApproxLevelSharp(int level);
147  int GetApproxLevelSharp() const { return _approxLevelSharp; }
148 
149  private:
150  // Member variables:
151  FVarID _dfltFVarID;
152 
153  SurfaceFactoryCache * _externCache;
154 
155  unsigned char _enableCache : 1;
156  unsigned char _approxLevelSmooth;
157  unsigned char _approxLevelSharp;
158  };
159 
160 public:
161  ~SurfaceFactory() override;
162 
164 
170  Sdc::SchemeType GetSchemeType() const { return _subdivScheme; }
171 
173  Sdc::Options GetSchemeOptions() const { return _subdivOptions; }
175 
176 public:
178 
200  bool FaceHasLimitSurface(Index faceIndex) const;
201 
210 
211 public:
213 
241  template <typename REAL>
242  bool InitVertexSurface(Index faceIndex, Surface<REAL> * surface) const;
243 
251  template <typename REAL>
252  bool InitVaryingSurface(Index faceIndex, Surface<REAL> * surface) const;
253 
266  template <typename REAL>
267  bool InitFaceVaryingSurface(Index faceIndex, Surface<REAL> * surface) const;
268 
278  template <typename REAL>
279  bool InitFaceVaryingSurface(Index faceIndex, Surface<REAL> * surface,
280  FVarID fvarID) const;
281 
307  template <typename REAL>
308  bool InitSurfaces(Index faceIndex, Surface<REAL> * vtxSurface,
309  Surface<REAL> * fvarSurfaces,
310  FVarID const fvarIDs[] = 0,
311  int fvarCount = 0,
312  Surface<REAL> * varSurface = 0) const;
314 
316  //
320  // WIP - considering removing these since non-essential
321  //
322 
324  template <typename REAL=float>
325  Surface<REAL> * CreateVertexSurface(Index faceIndex) const;
326 
328  template <typename REAL=float>
329  Surface<REAL> * CreateVaryingSurface(Index faceIndex) const;
330 
332  template <typename REAL=float>
333  Surface<REAL> * CreateFaceVaryingSurface(Index faceIndex) const;
334 
336  template <typename REAL=float>
337  Surface<REAL> * CreateFaceVaryingSurface(Index faceIndex, FVarID id) const;
339 
340 protected:
342 
358  SurfaceFactory(Sdc::SchemeType schemeType,
359  Sdc::Options const & schemeOptions,
360  Options const & limitOptions);
361 
364 
365  SurfaceFactory(SurfaceFactory const &) = delete;
366  SurfaceFactory & operator=(SurfaceFactory const &) = delete;
368 
369 private:
370  // Supporting internal methods:
371  void setSubdivisionOptions(Sdc::SchemeType, Sdc::Options const & options);
372  void setFactoryOptions(Options const & factoryOptions);
373 
374  bool faceHasLimitSimple(Index faceIndex, int faceSize) const;
375 
376  bool faceHasLimitNeighborhood(Index faceIndex) const;
377  bool faceHasLimitNeighborhood(FaceTopology const & faceTopology) const;
378 
379  class SurfaceSet;
380 
381  bool populateAllSurfaces( Index faceIndex, SurfaceSet * sSetPtr) const;
382  bool populateLinearSurfaces( Index faceIndex, SurfaceSet * sSetPtr) const;
383  bool populateNonLinearSurfaces(Index faceIndex, SurfaceSet * sSetPtr) const;
384 
385  bool initSurfaces(Index faceIndex, internal::SurfaceData * vtxSurface,
386  internal::SurfaceData * varSurface,
387  internal::SurfaceData * fvarSurfaces,
388  int fvarCount,
389  FVarID const fvarIDs[]) const;
390 
391  // Methods to assemble topology and corresponding indices for entire face:
392  bool isFaceNeighborhoodRegular(Index faceIndex,
393  FVarID const * fvarPtrOrVtx,
394  Index indices[]) const;
395 
396  bool initFaceNeighborhoodTopology(Index faceIndex,
397  FaceTopology * topology) const;
398 
399  bool gatherFaceNeighborhoodTopology(Index faceIndex,
400  FaceTopology * topology) const;
401 
402  int gatherFaceNeighborhoodIndices(Index faceIndex,
403  FaceTopology const & topology,
404  FVarID const * fvarPtrOrVtx,
405  Index indices[]) const;
406 
407  // Methods to assemble Surfaces for the different categories of patch:
408  typedef internal::SurfaceData SurfaceType;
409 
410  void assignLinearSurface(SurfaceType * surfacePtr,
411  Index faceIndex,
412  FVarID const * fvarPtrOrVtx) const;
413 
414  void assignRegularSurface(SurfaceType * surfacePtr,
415  Index const surfacePatchPoints[]) const;
416 
417  void assignRegularSurface(SurfaceType * surfacePtr,
418  FaceSurface const & surfaceDescription) const;
419 
420  void assignIrregularSurface(SurfaceType * surfacePtr,
421  FaceSurface const & surfaceDescription) const;
422 
423  void copyNonLinearSurface(SurfaceType * surfacePtr,
424  SurfaceType const & surfaceSource,
425  FaceSurface const & surfaceDescription) const;
426 
427 private:
428  // Members describing options and subdivision properties (very little
429  // memory and low initialization cost)
430  Sdc::SchemeType _subdivScheme;
431  Sdc::Options _subdivOptions;
432  Options _factoryOptions;
433 
434  // Members related to subdivision topology, options and limit tests:
435  unsigned int _linearScheme : 1;
436  unsigned int _linearFVarInterp : 1;
437 
438  unsigned int _testNeighborhoodForLimit : 1;
439  unsigned int _rejectSmoothBoundariesForLimit : 1;
440  unsigned int _rejectIrregularFacesForLimit : 1;
441 
442  int _regFaceSize;
443 
444  // Members related to caching:
445  SurfaceFactoryCache mutable * _topologyCache;
446 };
447 
448 //
449 // Inline methods for Options:
450 //
451 inline SurfaceFactory::Options &
453  _dfltFVarID = id;
454  return *this;
455 }
458  _enableCache = on;
459  return *this;
460 }
461 inline SurfaceFactory::Options &
463  _externCache = c;
464  return *this;
465 }
468  _approxLevelSmooth = (unsigned char) level;
469  return *this;
470 }
473  _approxLevelSharp = (unsigned char) level;
474  return *this;
475 }
476 
477 //
478 // Inline methods to initializes Surfaces:
479 //
480 template <typename REAL>
481 inline bool
483 
484  return initSurfaces(face, &s->getSurfaceData(), 0, 0, 0, 0);
485 }
486 template <typename REAL>
487 inline bool
489 
490  return initSurfaces(face, 0, &s->getSurfaceData(), 0, 0, 0);
491 }
492 template <typename REAL>
493 inline bool
495  FVarID fvarID) const {
496  return initSurfaces(face, 0, 0, &s->getSurfaceData(), 1, &fvarID);
497 }
498 template <typename REAL>
499 inline bool
501  FVarID dfltID = _factoryOptions.GetDefaultFVarID();
502  return initSurfaces(face, 0, 0, &s->getSurfaceData(), 1, &dfltID);
503 }
504 
505 template <typename REAL>
506 inline bool
508  Surface<REAL> * fvarSurfaces, FVarID const fvarIDs[], int fvarCount,
509  Surface<REAL> * varSurface) const {
510 
511  bool useDfltFVarID = fvarSurfaces && (fvarIDs == 0) && (fvarCount == 0);
512  FVarID dfltFVarID = useDfltFVarID ? _factoryOptions.GetDefaultFVarID() : 0;
513 
514  return initSurfaces(faceIndex,
515  vtxSurface ? &vtxSurface->getSurfaceData() : 0,
516  varSurface ? &varSurface->getSurfaceData() : 0,
517  fvarSurfaces ? &fvarSurfaces->getSurfaceData() : 0,
518  fvarCount ? fvarCount : (fvarSurfaces != 0),
519  useDfltFVarID ? &dfltFVarID : fvarIDs);
520 }
521 
522 //
523 // Inline methods to allocate and initialize Surfaces:
524 //
525 template <typename REAL>
526 inline Surface<REAL> *
528  Surface<REAL> * s = new Surface<REAL>();
529  if (InitVertexSurface<REAL>(faceIndex, s)) return s;
530  delete s;
531  return 0;
532 }
533 template <typename REAL>
534 inline Surface<REAL> *
536  Surface<REAL> * s = new Surface<REAL>();
537  if (InitVaryingSurface<REAL>(faceIndex, s)) return s;
538  delete s;
539  return 0;
540 }
541 template <typename REAL>
542 inline Surface<REAL> *
544  Surface<REAL> * s = new Surface<REAL>();
545  if (InitFaceVaryingSurface<REAL>(faceIndex, s, fvarID)) return s;
546  delete s;
547  return 0;
548 }
549 template <typename REAL>
550 inline Surface<REAL> *
552  FVarID dfltID = _factoryOptions.GetDefaultFVarID();
553  return CreateFaceVaryingSurface<REAL>(face, dfltID);
554 }
555 
556 } // end namespace Bfr
557 
558 } // end namespace OPENSUBDIV_VERSION
559 using namespace OPENSUBDIV_VERSION;
560 
561 } // end namespace OpenSubdiv
562 
563 #endif /* OPENSUBDIV3_BFR_SURFACE_FACTORY_H */
int GetApproxLevelSmooth() const
Return maximum refinement level for smooth features.
Sdc::SchemeType GetSchemeType() const
Return the subdivision scheme.
bool InitFaceVaryingSurface(Index faceIndex, Surface< REAL > *surface) const
Initialize a Surface for the default face-varying data.
Surface< REAL > * CreateVertexSurface(Index faceIndex) const
Construct a Surface for vertex data.
bool InitVaryingSurface(Index faceIndex, Surface< REAL > *surface) const
Initialize a Surface for varying data.
void setInternalCache(SurfaceFactoryCache *cache)
Subclass to identify an internal cache for use by base class.
Options & SetExternalCache(SurfaceFactoryCache *c)
Assign an external cache to override the internal.
Simple class defining the 2D parameterization of a face.
bool InitVertexSurface(Index faceIndex, Surface< REAL > *surface) const
Initialize a Surface for vertex data.
Base class providing initialization of a Surface for each face of a mesh.
SchemeType
Enumerated type for all subdivision schemes supported by OpenSubdiv.
Definition: types.h:37
bool FaceHasLimitSurface(Index faceIndex) const
Return if a specified face has a limit surface.
Options & SetApproxLevelSmooth(int level)
Assign maximum refinement level for smooth features.
Options & SetDefaultFVarID(FVarID id)
Assign the default face-varying ID (none assigned by default)
SurfaceFactory & operator=(SurfaceFactory const &)=delete
Container used internally by SurfaceFactory to store reusable information.
All supported options applying to subdivision scheme.
Definition: options.h:51
FVarID GetDefaultFVarID() const
Return the default face-varying ID.
std::intptr_t FVarID
Type used to identify and specify face-varying primvars.
int GetApproxLevelSharp() const
Return maximum refinement level for sharp features.
SurfaceFactoryCache * GetExternalCache() const
Return any assigned external cache.
Sdc::Options GetSchemeOptions() const
Return the set of subdivision options.
Abstract interface adapting SurfaceFactory to a connected mesh representation.
Simple set of options assigned to instances of SurfaceFactory.
Encapsulates the limit surface for a face of a mesh.
Definition: surface.h:59
bool InitSurfaces(Index faceIndex, Surface< REAL > *vtxSurface, Surface< REAL > *fvarSurfaces, FVarID const fvarIDs[]=0, int fvarCount=0, Surface< REAL > *varSurface=0) const
Initialize multiple Surfaces at once.
Surface< REAL > * CreateVaryingSurface(Index faceIndex) const
Construct a Surface for varying data.
SurfaceFactory(Sdc::SchemeType schemeType, Sdc::Options const &schemeOptions, Options const &limitOptions)
Constructor to be used by subclasses.
Parameterization GetFaceParameterization(Index faceIndex) const
Return the Parameterization of a face with a limit surface.
Surface< REAL > * CreateFaceVaryingSurface(Index faceIndex) const
Construct a Surface for the default face-varying data.
bool IsCachingEnabled() const
Return if caching is enable.
Options & EnableCaching(bool on)
Enable or disable caching (default is true):
Options & SetApproxLevelSharp(int level)
Assign maximum refinement level for sharp features.