Add Chromium-only Blender WebEngine parity work
This commit is contained in:
315
blender-5.2.0/extern/opensubdiv-source/opensubdiv/far/patchBuilder.h
vendored
Normal file
315
blender-5.2.0/extern/opensubdiv-source/opensubdiv/far/patchBuilder.h
vendored
Normal file
@@ -0,0 +1,315 @@
|
||||
//
|
||||
// Copyright 2017 DreamWorks Animation LLC.
|
||||
//
|
||||
// Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
// https://opensubdiv.org/license.
|
||||
//
|
||||
|
||||
#ifndef OPENSUBDIV3_FAR_PATCH_BUILDER_H
|
||||
#define OPENSUBDIV3_FAR_PATCH_BUILDER_H
|
||||
|
||||
#include "../version.h"
|
||||
|
||||
#include "../sdc/types.h"
|
||||
#include "../far/types.h"
|
||||
#include "../far/topologyRefiner.h"
|
||||
#include "../far/patchDescriptor.h"
|
||||
#include "../far/patchParam.h"
|
||||
#include "../far/ptexIndices.h"
|
||||
#include "../far/sparseMatrix.h"
|
||||
|
||||
|
||||
namespace OpenSubdiv {
|
||||
namespace OPENSUBDIV_VERSION {
|
||||
|
||||
namespace Far {
|
||||
|
||||
//
|
||||
// SourcePatch
|
||||
//
|
||||
// This is a local utility class that captures the full local topology of an
|
||||
// arbitrarily irregular patch, i.e. a patch which may have one or all corners
|
||||
// irregular. Given the topology at each corner the entire collection of
|
||||
// points involved is identified and oriented consistently.
|
||||
//
|
||||
// Note (barfowl):
|
||||
// This was originally a class internal to PatchBuilder, but there is some
|
||||
// redundancy between it and the Level::VSpan used more publicly to identify
|
||||
// irregular corner topology. Replacing VSpan with SourcePatch is now under
|
||||
// consideration, and doing so will impact its public/private interface (which
|
||||
// was left public to give PatchBuilder access).
|
||||
// A simpler constructor to initialize an instance given a set of Corners
|
||||
// would also be preferable if made more public (i.e. public for use within
|
||||
// the library, not exported to clients) -- eliminating the need for the
|
||||
// explicit initialization and required call to the Finalize() method that
|
||||
// the PatchBuilder currently performs internally.
|
||||
//
|
||||
class SourcePatch {
|
||||
public:
|
||||
struct Corner {
|
||||
Corner() { std::memset((void*) this, 0, sizeof(Corner)); }
|
||||
|
||||
LocalIndex _numFaces; // valence of corner vertex
|
||||
LocalIndex _patchFace; // location of patch within incident faces
|
||||
|
||||
unsigned short _boundary : 1;
|
||||
unsigned short _sharp : 1;
|
||||
unsigned short _dart : 1;
|
||||
|
||||
// For internal bookkeeping -- consider hiding or moving elsewhere
|
||||
unsigned short _sharesWithPrev : 1;
|
||||
unsigned short _sharesWithNext : 1;
|
||||
unsigned short _val2Interior : 1;
|
||||
unsigned short _val2Adjacent : 1;
|
||||
};
|
||||
|
||||
public:
|
||||
SourcePatch() { std::memset((void*) this, 0, sizeof(SourcePatch)); }
|
||||
~SourcePatch() { }
|
||||
|
||||
// To be called after all Corners have been initialized (hope to
|
||||
// replace this with alternative constructor at some point)
|
||||
void Finalize(int size3or4);
|
||||
|
||||
int GetNumSourcePoints() const { return _numSourcePoints; }
|
||||
int GetMaxValence() const { return _maxValence; }
|
||||
int GetMaxRingSize() const { return _maxRingSize; }
|
||||
|
||||
int GetCornerRingSize(int corner) const { return _ringSizes[corner]; }
|
||||
int GetCornerRingPoints(int corner, int points[]) const;
|
||||
|
||||
// public/private access needs to be reviewed when/if used more publicly
|
||||
//private:
|
||||
public:
|
||||
// The SourcePatch is fully defined by its Corner members
|
||||
Corner _corners[4];
|
||||
int _numCorners;
|
||||
|
||||
// Additional members (derived from Corners) to help assemble corner rings:
|
||||
int _numSourcePoints;
|
||||
int _maxValence;
|
||||
int _maxRingSize;
|
||||
|
||||
int _ringSizes[4];
|
||||
int _localRingSizes[4];
|
||||
int _localRingOffsets[4];
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// PatchBuilder
|
||||
//
|
||||
// This is the main class to assist the identification of limit surface
|
||||
// patches from faces in a TopologyRefiner for assembly into other, larger
|
||||
// datatypes.
|
||||
//
|
||||
// The PatchBuilder takes a const reference to a refiner and supports
|
||||
// arbitrarily refined hierarchies, i.e. it is not restricted to uniform or
|
||||
// adaptive refinement strategies and does not include any logic relating
|
||||
// to the origin of the hierarchy. It can associate a patch with any face
|
||||
// in the hierarchy (subject to a few minimum requirements) -- leaving the
|
||||
// decision as to which faces/patches are appropriate to its client.
|
||||
//
|
||||
// PatchBuilder is an abstract base class with a subclass derived to support
|
||||
// each subdivision scheme -- as such, construction relies on a factory
|
||||
// method to create an instance of the appropriate subclass. Only two pure
|
||||
// virtual methods are required (other than the required destructor):
|
||||
//
|
||||
// - determine the patch type for a subdivision scheme given a more
|
||||
// general basis specification (e.g. Bezier, Gregory, Linear, etc)
|
||||
//
|
||||
// - convert the vertices in the subdivision hierarchy into points of a
|
||||
// specified patch type, using computations specific to that scheme
|
||||
//
|
||||
// The base class handles the more general topological analysis that
|
||||
// determines the nature of a patch associated with each face -- providing
|
||||
// both queries to the client, along with more involved methods to extract
|
||||
// or convert data associated with the patches. There is no concrete "Patch"
|
||||
// class to which all clients would be required to conform. The queries and
|
||||
// data returned are provided for clients to assemble into patches or other
|
||||
// aggregates as they see fit.
|
||||
//
|
||||
// This is intended as an internal/private class for use within the library
|
||||
// for now -- possibly to be exported for use by clients when/if its
|
||||
// interface is appropriate and stable.
|
||||
//
|
||||
class PatchBuilder {
|
||||
public:
|
||||
//
|
||||
// A PatchBuilder is constructed given a patch "basis" rather than a
|
||||
// "type" to use with the subdivision scheme involved. The relevant
|
||||
// explicit patch types will be determined from the basis and scheme:
|
||||
//
|
||||
enum BasisType {
|
||||
BASIS_UNSPECIFIED,
|
||||
BASIS_REGULAR,
|
||||
BASIS_GREGORY,
|
||||
BASIS_LINEAR,
|
||||
BASIS_BEZIER // to be supported in future
|
||||
};
|
||||
|
||||
//
|
||||
// Required Options specify a patch basis to use for both regular and
|
||||
// irregular patches -- sparing the client the need to repeatedly
|
||||
// specify these for each face considered. Other options are included
|
||||
// to support legacy approximations:
|
||||
//
|
||||
struct Options {
|
||||
Options() : regBasisType(BASIS_UNSPECIFIED),
|
||||
irregBasisType(BASIS_UNSPECIFIED),
|
||||
fillMissingBoundaryPoints(false),
|
||||
approxInfSharpWithSmooth(false),
|
||||
approxSmoothCornerWithSharp(false) { }
|
||||
|
||||
BasisType regBasisType;
|
||||
BasisType irregBasisType;
|
||||
bool fillMissingBoundaryPoints;
|
||||
bool approxInfSharpWithSmooth;
|
||||
bool approxSmoothCornerWithSharp;
|
||||
};
|
||||
|
||||
public:
|
||||
//
|
||||
// Public construction (via factory method) and destruction:
|
||||
//
|
||||
static PatchBuilder* Create(TopologyRefiner const& refiner,
|
||||
Options const& options);
|
||||
virtual ~PatchBuilder();
|
||||
|
||||
//
|
||||
// High-level queries related to the subdivision scheme of the refiner, the
|
||||
// patch types associated with it and those chosen to represent its faces:
|
||||
//
|
||||
int GetRegularFaceSize() const { return _schemeRegFaceSize; }
|
||||
|
||||
BasisType GetRegularBasisType() const { return _options.regBasisType; }
|
||||
BasisType GetIrregularBasisType() const { return _options.irregBasisType; }
|
||||
|
||||
PatchDescriptor::Type GetRegularPatchType() const { return _regPatchType; }
|
||||
PatchDescriptor::Type GetIrregularPatchType() const { return _irregPatchType; }
|
||||
|
||||
PatchDescriptor::Type GetNativePatchType() const { return _nativePatchType; }
|
||||
PatchDescriptor::Type GetLinearPatchType() const { return _linearPatchType; }
|
||||
|
||||
//
|
||||
// Face-level queries to determine presence of patches:
|
||||
//
|
||||
bool IsFaceAPatch(int level, Index face) const;
|
||||
bool IsFaceALeaf(int level, Index face) const;
|
||||
|
||||
//
|
||||
// Patch-level topological queries:
|
||||
//
|
||||
bool IsPatchRegular(int level, Index face, int fvc = -1) const;
|
||||
|
||||
int GetRegularPatchBoundaryMask(int level, Index face, int fvc = -1) const;
|
||||
|
||||
void GetIrregularPatchCornerSpans(int level, Index face,
|
||||
Vtr::internal::Level::VSpan cornerSpans[4], int fvc = -1) const;
|
||||
|
||||
bool DoesFaceVaryingPatchMatch(int level, Index face, int fvc) const {
|
||||
return _refiner.getLevel(level).doesFaceFVarTopologyMatch(face, fvc);
|
||||
}
|
||||
|
||||
//
|
||||
// Patch-level control point retrieval and methods for converting source
|
||||
// points to a set of local points in a different basis
|
||||
//
|
||||
int GetRegularPatchPoints(int level, Index face,
|
||||
int regBoundaryMask, // compute internally when < 0
|
||||
Index patchPoints[],
|
||||
int fvc = -1) const;
|
||||
|
||||
template <typename REAL>
|
||||
int GetIrregularPatchConversionMatrix(int level, Index face,
|
||||
Vtr::internal::Level::VSpan const cornerSpans[],
|
||||
SparseMatrix<REAL> & matrix) const;
|
||||
|
||||
int GetIrregularPatchSourcePoints(int level, Index face,
|
||||
Vtr::internal::Level::VSpan const cornerSpans[],
|
||||
Index sourcePoints[],
|
||||
int fvc = -1) const;
|
||||
//
|
||||
// Queries related to "single-crease" patches -- currently a subset of
|
||||
// regular interior patches:
|
||||
//
|
||||
struct SingleCreaseInfo {
|
||||
int creaseEdgeInFace;
|
||||
float creaseSharpness;
|
||||
};
|
||||
bool IsRegularSingleCreasePatch(int level, Index face,
|
||||
SingleCreaseInfo & info) const;
|
||||
|
||||
//
|
||||
// Computing the PatchParam -- note the regrettable dependency on
|
||||
// PtexIndices but PatchParam is essentially tied to it indefinitely.
|
||||
// Better to pass it in than have the PatchBuilder build its own
|
||||
// PtexIndices.
|
||||
//
|
||||
// Consider creating a PatchParamFactory which can manage the PtexIndices
|
||||
// along with this method. It will then be able to generate additional
|
||||
// data to accelerate these computations.
|
||||
//
|
||||
PatchParam ComputePatchParam(int level, Index face,
|
||||
PtexIndices const& ptexIndices, bool isRegular = true,
|
||||
int boundaryMask = 0, bool computeTransitionMask = false) const;
|
||||
|
||||
protected:
|
||||
PatchBuilder(TopologyRefiner const& refiner, Options const& options);
|
||||
|
||||
// Internal methods supporting topology queries:
|
||||
int getRegularFacePoints(int level, Index face,
|
||||
Index patchPoints[], int fvc) const;
|
||||
|
||||
int getQuadRegularPatchPoints(int level, Index face,
|
||||
int regBoundaryMask, Index patchPoints[], int fvc) const;
|
||||
|
||||
int getTriRegularPatchPoints(int level, Index face,
|
||||
int regBoundaryMask, Index patchPoints[], int fvc) const;
|
||||
|
||||
// Internal methods using the SourcePatch:
|
||||
int assembleIrregularSourcePatch(int level, Index face,
|
||||
Vtr::internal::Level::VSpan const cornerSpans[],
|
||||
SourcePatch & sourcePatch) const;
|
||||
|
||||
int gatherIrregularSourcePoints(int level, Index face,
|
||||
Vtr::internal::Level::VSpan const cornerSpans[],
|
||||
SourcePatch & sourcePatch,
|
||||
Index patchPoints[], int fvc) const;
|
||||
|
||||
protected:
|
||||
//
|
||||
// Virtual methods to be provided by subclass for each scheme:
|
||||
//
|
||||
virtual PatchDescriptor::Type patchTypeFromBasis(BasisType basis) const = 0;
|
||||
|
||||
// Note overloading of the conversion for SparseMatrix<REAL>:
|
||||
virtual int convertToPatchType(SourcePatch const & sourcePatch,
|
||||
PatchDescriptor::Type patchType,
|
||||
SparseMatrix<float> & matrix) const = 0;
|
||||
virtual int convertToPatchType(SourcePatch const & sourcePatch,
|
||||
PatchDescriptor::Type patchType,
|
||||
SparseMatrix<double> & matrix) const = 0;
|
||||
|
||||
protected:
|
||||
TopologyRefiner const& _refiner;
|
||||
Options const _options;
|
||||
|
||||
Sdc::SchemeType _schemeType;
|
||||
int _schemeRegFaceSize;
|
||||
bool _schemeIsLinear;
|
||||
|
||||
PatchDescriptor::Type _regPatchType;
|
||||
PatchDescriptor::Type _irregPatchType;
|
||||
PatchDescriptor::Type _nativePatchType;
|
||||
PatchDescriptor::Type _linearPatchType;
|
||||
};
|
||||
|
||||
} // end namespace Far
|
||||
|
||||
} // end namespace OPENSUBDIV_VERSION
|
||||
using namespace OPENSUBDIV_VERSION;
|
||||
|
||||
} // end namespace OpenSubdiv
|
||||
|
||||
#endif /* OPENSUBDIV3_FAR_PATCH_BUILDER_H */
|
||||
Reference in New Issue
Block a user