OpenSubdiv
Loading...
Searching...
No Matches
surfaceFactory.h
Go to the documentation of this file.
1//
2// Copyright 2021 Pixar
3//
4// Licensed under the terms set forth in the LICENSE.txt file available at
5// https://opensubdiv.org/license.
6//
7
8#ifndef OPENSUBDIV3_BFR_SURFACE_FACTORY_H
9#define OPENSUBDIV3_BFR_SURFACE_FACTORY_H
10
11#include "../version.h"
12
13#include "../bfr/surface.h"
15#include "../sdc/options.h"
16#include "../sdc/types.h"
17
18#include <cstdint>
19
20namespace OpenSubdiv {
21namespace OPENSUBDIV_VERSION {
22
23namespace Bfr {
24
25//
26// Forward declarations of public and internal classes used by factories:
27//
28class SurfaceFactoryCache;
29class FaceTopology;
30class FaceSurface;
31
87public:
99 class Options {
100 public:
101 Options() : _dfltFVarID(-1), _externCache(0), _enableCache(true),
102 _approxLevelSmooth(2), _approxLevelSharp(6) { }
103
108 FVarID GetDefaultFVarID() const { return _dfltFVarID; }
109
111 Options & EnableCaching(bool on);
113 bool IsCachingEnabled() const { return _enableCache; }
114
118 SurfaceFactoryCache * GetExternalCache() const { return _externCache; }
119
120 // Set refinement levels used to approximate the limit surface
121 // for smooth and sharp features (reasonable defaults assigned):
123 Options & SetApproxLevelSmooth(int level);
125 int GetApproxLevelSmooth() const { return _approxLevelSmooth; }
126
128 Options & SetApproxLevelSharp(int level);
130 int GetApproxLevelSharp() const { return _approxLevelSharp; }
131
132 private:
133 // Member variables:
134 FVarID _dfltFVarID;
135
136 SurfaceFactoryCache * _externCache;
137
138 unsigned char _enableCache : 1;
139 unsigned char _approxLevelSmooth;
140 unsigned char _approxLevelSharp;
141 };
142
143public:
144 ~SurfaceFactory() override;
145
147
151
153 Sdc::SchemeType GetSchemeType() const { return _subdivScheme; }
154
156 Sdc::Options GetSchemeOptions() const { return _subdivOptions; }
158
159public:
161
173
183 bool FaceHasLimitSurface(Index faceIndex) const;
184
193
194public:
196
216
224 template <typename REAL>
225 bool InitVertexSurface(Index faceIndex, Surface<REAL> * surface) const;
226
234 template <typename REAL>
235 bool InitVaryingSurface(Index faceIndex, Surface<REAL> * surface) const;
236
249 template <typename REAL>
250 bool InitFaceVaryingSurface(Index faceIndex, Surface<REAL> * surface) const;
251
261 template <typename REAL>
262 bool InitFaceVaryingSurface(Index faceIndex, Surface<REAL> * surface,
263 FVarID fvarID) const;
264
290 template <typename REAL>
291 bool InitSurfaces(Index faceIndex, Surface<REAL> * vtxSurface,
292 Surface<REAL> * fvarSurfaces,
293 FVarID const fvarIDs[] = 0,
294 int fvarCount = 0,
295 Surface<REAL> * varSurface = 0) const;
297
299
302 //
303 // WIP - considering removing these since non-essential
304 //
305
307 template <typename REAL=float>
308 Surface<REAL> * CreateVertexSurface(Index faceIndex) const;
309
311 template <typename REAL=float>
312 Surface<REAL> * CreateVaryingSurface(Index faceIndex) const;
313
315 template <typename REAL=float>
317
319 template <typename REAL=float>
320 Surface<REAL> * CreateFaceVaryingSurface(Index faceIndex, FVarID id) const;
322
323protected:
325
329
342 Sdc::Options const & schemeOptions,
343 Options const & limitOptions);
344
347
351
352private:
353 // Supporting internal methods:
354 void setSubdivisionOptions(Sdc::SchemeType, Sdc::Options const & options);
355 void setFactoryOptions(Options const & factoryOptions);
356
357 bool faceHasLimitSimple(Index faceIndex, int faceSize) const;
358
359 bool faceHasLimitNeighborhood(Index faceIndex) const;
360 bool faceHasLimitNeighborhood(FaceTopology const & faceTopology) const;
361
362 class SurfaceSet;
363
364 bool populateAllSurfaces( Index faceIndex, SurfaceSet * sSetPtr) const;
365 bool populateLinearSurfaces( Index faceIndex, SurfaceSet * sSetPtr) const;
366 bool populateNonLinearSurfaces(Index faceIndex, SurfaceSet * sSetPtr) const;
367
368 bool initSurfaces(Index faceIndex, internal::SurfaceData * vtxSurface,
369 internal::SurfaceData * varSurface,
370 internal::SurfaceData * fvarSurfaces,
371 int fvarCount,
372 FVarID const fvarIDs[]) const;
373
374 // Methods to assemble topology and corresponding indices for entire face:
375 bool isFaceNeighborhoodRegular(Index faceIndex,
376 FVarID const * fvarPtrOrVtx,
377 Index indices[]) const;
378
379 bool initFaceNeighborhoodTopology(Index faceIndex,
380 FaceTopology * topology) const;
381
382 bool gatherFaceNeighborhoodTopology(Index faceIndex,
383 FaceTopology * topology) const;
384
385 int gatherFaceNeighborhoodIndices(Index faceIndex,
386 FaceTopology const & topology,
387 FVarID const * fvarPtrOrVtx,
388 Index indices[]) const;
389
390 // Methods to assemble Surfaces for the different categories of patch:
391 typedef internal::SurfaceData SurfaceType;
392
393 void assignLinearSurface(SurfaceType * surfacePtr,
394 Index faceIndex,
395 FVarID const * fvarPtrOrVtx) const;
396
397 void assignRegularSurface(SurfaceType * surfacePtr,
398 Index const surfacePatchPoints[]) const;
399
400 void assignRegularSurface(SurfaceType * surfacePtr,
401 FaceSurface const & surfaceDescription) const;
402
403 void assignIrregularSurface(SurfaceType * surfacePtr,
404 FaceSurface const & surfaceDescription) const;
405
406 void copyNonLinearSurface(SurfaceType * surfacePtr,
407 SurfaceType const & surfaceSource,
408 FaceSurface const & surfaceDescription) const;
409
410private:
411 // Members describing options and subdivision properties (very little
412 // memory and low initialization cost)
413 Sdc::SchemeType _subdivScheme;
414 Sdc::Options _subdivOptions;
415 Options _factoryOptions;
416
417 // Members related to subdivision topology, options and limit tests:
418 unsigned int _linearScheme : 1;
419 unsigned int _linearFVarInterp : 1;
420
421 unsigned int _testNeighborhoodForLimit : 1;
422 unsigned int _rejectSmoothBoundariesForLimit : 1;
423 unsigned int _rejectIrregularFacesForLimit : 1;
424
425 int _regFaceSize;
426
427 // Members related to caching:
428 SurfaceFactoryCache mutable * _topologyCache;
429};
430
431//
432// Inline methods for Options:
433//
436 _dfltFVarID = id;
437 return *this;
438}
441 _enableCache = on;
442 return *this;
443}
446 _externCache = c;
447 return *this;
448}
451 _approxLevelSmooth = (unsigned char) level;
452 return *this;
453}
456 _approxLevelSharp = (unsigned char) level;
457 return *this;
458}
459
460//
461// Inline methods to initializes Surfaces:
462//
463template <typename REAL>
464inline bool
466
467 return initSurfaces(face, &s->getSurfaceData(), 0, 0, 0, 0);
468}
469template <typename REAL>
470inline bool
472
473 return initSurfaces(face, 0, &s->getSurfaceData(), 0, 0, 0);
474}
475template <typename REAL>
476inline bool
478 FVarID fvarID) const {
479 return initSurfaces(face, 0, 0, &s->getSurfaceData(), 1, &fvarID);
480}
481template <typename REAL>
482inline bool
484 FVarID dfltID = _factoryOptions.GetDefaultFVarID();
485 return initSurfaces(face, 0, 0, &s->getSurfaceData(), 1, &dfltID);
486}
487
488template <typename REAL>
489inline bool
491 Surface<REAL> * fvarSurfaces, FVarID const fvarIDs[], int fvarCount,
492 Surface<REAL> * varSurface) const {
493
494 bool useDfltFVarID = fvarSurfaces && (fvarIDs == 0) && (fvarCount == 0);
495 FVarID dfltFVarID = useDfltFVarID ? _factoryOptions.GetDefaultFVarID() : 0;
496
497 return initSurfaces(faceIndex,
498 vtxSurface ? &vtxSurface->getSurfaceData() : 0,
499 varSurface ? &varSurface->getSurfaceData() : 0,
500 fvarSurfaces ? &fvarSurfaces->getSurfaceData() : 0,
501 fvarCount ? fvarCount : (fvarSurfaces != 0),
502 useDfltFVarID ? &dfltFVarID : fvarIDs);
503}
504
505//
506// Inline methods to allocate and initialize Surfaces:
507//
508template <typename REAL>
509inline Surface<REAL> *
511 Surface<REAL> * s = new Surface<REAL>();
512 if (InitVertexSurface<REAL>(faceIndex, s)) return s;
513 delete s;
514 return 0;
515}
516template <typename REAL>
517inline Surface<REAL> *
519 Surface<REAL> * s = new Surface<REAL>();
520 if (InitVaryingSurface<REAL>(faceIndex, s)) return s;
521 delete s;
522 return 0;
523}
524template <typename REAL>
525inline Surface<REAL> *
527 Surface<REAL> * s = new Surface<REAL>();
528 if (InitFaceVaryingSurface<REAL>(faceIndex, s, fvarID)) return s;
529 delete s;
530 return 0;
531}
532template <typename REAL>
533inline Surface<REAL> *
535 FVarID dfltID = _factoryOptions.GetDefaultFVarID();
536 return CreateFaceVaryingSurface<REAL>(face, dfltID);
537}
538
539} // end namespace Bfr
540
541} // end namespace OPENSUBDIV_VERSION
542using namespace OPENSUBDIV_VERSION;
543
544} // end namespace OpenSubdiv
545
546#endif /* OPENSUBDIV3_BFR_SURFACE_FACTORY_H */
SchemeType
Enumerated type for all subdivision schemes supported by OpenSubdiv.
Definition types.h:20
Simple class defining the 2D parameterization of a face.
Encapsulates the limit surface for a face of a mesh.
Definition surface.h:42
Base class providing initialization of a Surface for each face of a mesh.
void setInternalCache(SurfaceFactoryCache *cache)
Subclass to identify an internal cache for use by base class.
bool InitFaceVaryingSurface(Index faceIndex, Surface< REAL > *surface) const
Initialize a Surface for the default face-varying data.
Sdc::Options GetSchemeOptions() const
Return the set of subdivision options.
Parameterization GetFaceParameterization(Index faceIndex) const
Return the Parameterization of a face with a limit surface.
SurfaceFactory(SurfaceFactory const &)=delete
bool FaceHasLimitSurface(Index faceIndex) const
Return if a specified face has a limit surface.
SurfaceFactory & operator=(SurfaceFactory const &)=delete
Surface< REAL > * CreateVertexSurface(Index faceIndex) const
Construct a Surface for vertex data.
Surface< REAL > * CreateFaceVaryingSurface(Index faceIndex) const
Construct a Surface for the default face-varying data.
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.
Sdc::SchemeType GetSchemeType() const
Return the subdivision scheme.
Surface< REAL > * CreateVaryingSurface(Index faceIndex) const
Construct a Surface for varying data.
bool InitVertexSurface(Index faceIndex, Surface< REAL > *surface) const
Initialize a Surface for vertex data.
bool InitVaryingSurface(Index faceIndex, Surface< REAL > *surface) const
Initialize a Surface for varying data.
SurfaceFactory(Sdc::SchemeType schemeType, Sdc::Options const &schemeOptions, Options const &limitOptions)
Constructor to be used by subclasses.
Simple set of options assigned to instances of SurfaceFactory.
Options & SetExternalCache(SurfaceFactoryCache *c)
Assign an external cache to override the internal.
Options & EnableCaching(bool on)
Enable or disable caching (default is true):
Options & SetApproxLevelSmooth(int level)
Assign maximum refinement level for smooth features.
int GetApproxLevelSmooth() const
Return maximum refinement level for smooth features.
bool IsCachingEnabled() const
Return if caching is enable.
Options & SetDefaultFVarID(FVarID id)
Assign the default face-varying ID (none assigned by default)
Options & SetApproxLevelSharp(int level)
Assign maximum refinement level for sharp features.
FVarID GetDefaultFVarID() const
Return the default face-varying ID.
int GetApproxLevelSharp() const
Return maximum refinement level for sharp features.
SurfaceFactoryCache * GetExternalCache() const
Return any assigned external cache.
Container used internally by SurfaceFactory to store reusable information.
Abstract interface adapting SurfaceFactory to a connected mesh representation.
std::intptr_t FVarID
Type used to identify and specify face-varying primvars.
All supported options applying to subdivision scheme.
Definition options.h:34