mirror of
https://github.com/PixarAnimationStudios/OpenSubdiv
synced 2024-11-08 21:30:06 +00:00
Major public addition of class templates for multiple precision:
- converted classes for stencils, tables and factories to templates - added backward compatible class wrappers around new templates - extended PatchTable to support variable precision stencil tables - extended PatchTableBuilder to manage PatchTable's new stencil tables - templated PatchTableBuilder conversion from SparseMatrix to stencils - extended public PatchTableFactory interface to specify precision - converted PrimvarRefiner class to template and added wrapper class
This commit is contained in:
parent
f6172f9608
commit
647039a8ee
@ -35,9 +35,12 @@ namespace Far {
|
||||
|
||||
PatchTable::PatchTable(int maxvalence) :
|
||||
_maxValence(maxvalence),
|
||||
_localPointStencils(NULL),
|
||||
_localPointVaryingStencils(NULL),
|
||||
_varyingDesc(Far::PatchDescriptor::QUADS) {
|
||||
_localPointStencils(),
|
||||
_localPointVaryingStencils(),
|
||||
_varyingDesc(Far::PatchDescriptor::QUADS),
|
||||
_vertexPrecisionIsDouble(false),
|
||||
_varyingPrecisionIsDouble(false),
|
||||
_faceVaryingPrecisionIsDouble(false) {
|
||||
}
|
||||
|
||||
// Copy constructor
|
||||
@ -55,31 +58,31 @@ PatchTable::PatchTable(PatchTable const & src) :
|
||||
_varyingDesc(src._varyingDesc),
|
||||
_fvarChannels(src._fvarChannels),
|
||||
_sharpnessIndices(src._sharpnessIndices),
|
||||
_sharpnessValues(src._sharpnessValues) {
|
||||
_sharpnessValues(src._sharpnessValues),
|
||||
_vertexPrecisionIsDouble(src._vertexPrecisionIsDouble),
|
||||
_varyingPrecisionIsDouble(src._varyingPrecisionIsDouble),
|
||||
_faceVaryingPrecisionIsDouble(src._faceVaryingPrecisionIsDouble) {
|
||||
|
||||
if (src._localPointStencils) {
|
||||
_localPointStencils =
|
||||
new StencilTable(*src._localPointStencils);
|
||||
if (src._localPointStencils.IsSet()) {
|
||||
_localPointStencils = src._localPointStencils.Clone();
|
||||
}
|
||||
if (src._localPointVaryingStencils) {
|
||||
_localPointVaryingStencils =
|
||||
new StencilTable(*src._localPointVaryingStencils);
|
||||
if (src._localPointVaryingStencils.IsSet()) {
|
||||
_localPointVaryingStencils = src._localPointVaryingStencils.Clone();
|
||||
}
|
||||
if (! src._localPointFaceVaryingStencils.empty()) {
|
||||
_localPointFaceVaryingStencils.resize(src._localPointFaceVaryingStencils.size());
|
||||
for (int fvc=0; fvc<(int)_localPointFaceVaryingStencils.size(); ++fvc) {
|
||||
_localPointFaceVaryingStencils[fvc] =
|
||||
new StencilTable(*src._localPointFaceVaryingStencils[fvc]);
|
||||
}
|
||||
_localPointFaceVaryingStencils[fvc] = src._localPointFaceVaryingStencils[fvc].Clone();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PatchTable::~PatchTable() {
|
||||
delete _localPointStencils;
|
||||
delete _localPointVaryingStencils;
|
||||
_localPointStencils.Delete();
|
||||
_localPointVaryingStencils.Delete();
|
||||
for (int fvc=0; fvc<(int)_localPointFaceVaryingStencils.size(); ++fvc) {
|
||||
delete _localPointFaceVaryingStencils[fvc];
|
||||
}
|
||||
_localPointFaceVaryingStencils[fvc].Delete();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
@ -350,17 +353,17 @@ PatchTable::GetSingleCreasePatchSharpnessValue(int arrayIndex, int patchIndex) c
|
||||
|
||||
int
|
||||
PatchTable::GetNumLocalPoints() const {
|
||||
return _localPointStencils ? _localPointStencils->GetNumStencils() : 0;
|
||||
return _localPointStencils.IsSet() ? _localPointStencils.Size() : 0;
|
||||
}
|
||||
int
|
||||
PatchTable::GetNumLocalPointsVarying() const {
|
||||
return _localPointVaryingStencils ? _localPointVaryingStencils->GetNumStencils() : 0;
|
||||
return _localPointVaryingStencils.IsSet() ? _localPointVaryingStencils.Size() : 0;
|
||||
}
|
||||
int
|
||||
PatchTable::GetNumLocalPointsFaceVarying(int channel) const {
|
||||
if (channel>=0 && channel<(int)_localPointFaceVaryingStencils.size() &&
|
||||
_localPointFaceVaryingStencils[channel]) {
|
||||
return _localPointFaceVaryingStencils[channel]->GetNumStencils();
|
||||
if (channel>=0 && channel<(int)_localPointFaceVaryingStencils.size()) {
|
||||
return _localPointFaceVaryingStencils[channel].IsSet() ?
|
||||
_localPointFaceVaryingStencils[channel].Size() : 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -173,9 +173,15 @@ public:
|
||||
ComputeLocalPointValues(T const *src, T *dst) const;
|
||||
|
||||
/// \brief Returns the stencil table to compute local point vertex values
|
||||
StencilTable const *GetLocalPointStencilTable() const {
|
||||
return _localPointStencils;
|
||||
}
|
||||
StencilTable const *GetLocalPointStencilTable() const;
|
||||
|
||||
/// \brief Returns the stencil table to compute local point vertex values
|
||||
template <typename REAL>
|
||||
StencilTableReal<REAL> const *GetLocalPointStencilTable() const;
|
||||
|
||||
/// \brief Tests the precision of the stencil table to compute local point
|
||||
/// vertex values
|
||||
template <typename REAL> bool IsLocalPointStencilPrecision() const;
|
||||
|
||||
/// \brief Returns the number of local varying points.
|
||||
int GetNumLocalPointsVarying() const;
|
||||
@ -193,9 +199,15 @@ public:
|
||||
ComputeLocalPointValuesVarying(T const *src, T *dst) const;
|
||||
|
||||
/// \brief Returns the stencil table to compute local point varying values
|
||||
StencilTable const *GetLocalPointVaryingStencilTable() const {
|
||||
return _localPointVaryingStencils;
|
||||
}
|
||||
StencilTable const *GetLocalPointVaryingStencilTable() const;
|
||||
|
||||
/// \brief Returns the stencil table to compute local point varying values
|
||||
template <typename REAL>
|
||||
StencilTableReal<REAL> const *GetLocalPointVaryingStencilTable() const;
|
||||
|
||||
/// \brief Tests the precision of the stencil table to compute local point
|
||||
/// varying values
|
||||
template <typename REAL> bool IsLocalPointVaryingStencilPrecision() const;
|
||||
|
||||
/// \brief Returns the number of local face-varying points for \p channel
|
||||
int GetNumLocalPointsFaceVarying(int channel = 0) const;
|
||||
@ -215,12 +227,15 @@ public:
|
||||
ComputeLocalPointValuesFaceVarying(T const *src, T *dst, int channel = 0) const;
|
||||
|
||||
/// \brief Returns the stencil table to compute local point face-varying values
|
||||
StencilTable const *GetLocalPointFaceVaryingStencilTable(int channel = 0) const {
|
||||
if (channel >= 0 && channel < (int)_localPointFaceVaryingStencils.size()) {
|
||||
return _localPointFaceVaryingStencils[channel];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
StencilTable const *GetLocalPointFaceVaryingStencilTable(int channel = 0) const;
|
||||
|
||||
/// \brief Returns the stencil table to compute local point face-varying values
|
||||
template <typename REAL>
|
||||
StencilTableReal<REAL> const * GetLocalPointFaceVaryingStencilTable(int channel = 0) const;
|
||||
|
||||
/// \brief Tests the precision of the stencil table to compute local point
|
||||
/// face-varying values
|
||||
template <typename REAL> bool IsLocalPointFaceVaryingStencilPrecision() const;
|
||||
//@}
|
||||
|
||||
|
||||
@ -559,6 +574,58 @@ private:
|
||||
PatchParamArray getFVarPatchParams(int channel);
|
||||
PatchParam getPatchFVarPatchParam(int patch, int channel) const;
|
||||
|
||||
private:
|
||||
//
|
||||
// Private class to manage stencil table pointers of varying precision
|
||||
//
|
||||
// This implementation is still up for debate -- could be improved or
|
||||
// could be entirely replaced...
|
||||
//
|
||||
class StencilTableHandler {
|
||||
private:
|
||||
typedef StencilTableReal<float> float_type;
|
||||
typedef StencilTableReal<double> double_type;
|
||||
|
||||
void init() { _fPtr = 0, _isDouble = false; }
|
||||
void init(float_type * ptr) { _fPtr = ptr, _isDouble = false; }
|
||||
void init(double_type * ptr) { _dPtr = ptr, _isDouble = true; }
|
||||
|
||||
public:
|
||||
StencilTableHandler() { init(); }
|
||||
StencilTableHandler(float_type * ptr) { init(ptr); }
|
||||
StencilTableHandler(double_type * ptr) { init(ptr); }
|
||||
|
||||
// Generic accessor and modifiers:
|
||||
template <typename REAL> StencilTableReal<REAL> * Get() const;
|
||||
|
||||
void Set(float_type * ptr) { init(ptr); }
|
||||
void Set(double_type * ptr) { init(ptr); }
|
||||
|
||||
// Other utilities
|
||||
bool IsSet() const { return _fPtr != 0; }
|
||||
bool IsDouble() const { return _isDouble; }
|
||||
void Clear() { init(); }
|
||||
|
||||
int Size() const {
|
||||
return _isDouble ? _dPtr->GetNumStencils() : _fPtr->GetNumStencils();
|
||||
}
|
||||
void Delete() {
|
||||
if (_isDouble) delete _dPtr;
|
||||
else delete _fPtr;
|
||||
}
|
||||
StencilTableHandler Clone() const {
|
||||
return _isDouble ? StencilTableHandler(new double_type(*_dPtr))
|
||||
: StencilTableHandler(new float_type(*_fPtr));
|
||||
}
|
||||
|
||||
private:
|
||||
union {
|
||||
float_type * _fPtr;
|
||||
double_type * _dPtr;
|
||||
};
|
||||
bool _isDouble;
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
//
|
||||
@ -582,8 +649,9 @@ private:
|
||||
//
|
||||
QuadOffsetsTable _quadOffsetsTable; // Quad offsets (for Gregory patches)
|
||||
VertexValenceTable _vertexValenceTable; // Vertex valence table (for Gregory patches)
|
||||
StencilTable const * _localPointStencils; // endcap basis conversion stencils
|
||||
StencilTable const * _localPointVaryingStencils; // endcap varying stencils (for convenience)
|
||||
|
||||
StencilTableHandler _localPointStencils; // local point conversion stencils
|
||||
StencilTableHandler _localPointVaryingStencils; // local point varying stencils
|
||||
|
||||
//
|
||||
// Varying data
|
||||
@ -599,7 +667,7 @@ private:
|
||||
|
||||
FVarPatchChannelVector _fvarChannels;
|
||||
|
||||
std::vector<StencilTable const *> _localPointFaceVaryingStencils;
|
||||
std::vector<StencilTableHandler> _localPointFaceVaryingStencils;
|
||||
|
||||
//
|
||||
// 'single-crease' patch sharpness tables
|
||||
@ -607,21 +675,122 @@ private:
|
||||
|
||||
std::vector<Index> _sharpnessIndices; // Indices of single-crease sharpness (one per patch)
|
||||
std::vector<float> _sharpnessValues; // Sharpness values.
|
||||
|
||||
//
|
||||
// Precision -- only applies to local-point stencil tables
|
||||
//
|
||||
unsigned int _vertexPrecisionIsDouble : 1;
|
||||
unsigned int _varyingPrecisionIsDouble : 1;
|
||||
unsigned int _faceVaryingPrecisionIsDouble : 1;
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Template specializations for float/double -- to be defined before used:
|
||||
//
|
||||
template <> inline StencilTableReal<float> *
|
||||
PatchTable::StencilTableHandler::Get<float>() const { return _fPtr; }
|
||||
|
||||
template <> inline StencilTableReal<double> *
|
||||
PatchTable::StencilTableHandler::Get<double>() const { return _dPtr; }
|
||||
|
||||
template <> inline bool
|
||||
PatchTable::IsLocalPointStencilPrecision<float>() const {
|
||||
return !_vertexPrecisionIsDouble;
|
||||
}
|
||||
template <> inline bool
|
||||
PatchTable::IsLocalPointVaryingStencilPrecision<float>() const {
|
||||
return !_varyingPrecisionIsDouble;
|
||||
}
|
||||
template <> inline bool
|
||||
PatchTable::IsLocalPointFaceVaryingStencilPrecision<float>() const {
|
||||
return !_faceVaryingPrecisionIsDouble;
|
||||
}
|
||||
|
||||
template <> inline bool
|
||||
PatchTable::IsLocalPointStencilPrecision<double>() const {
|
||||
return _vertexPrecisionIsDouble;
|
||||
}
|
||||
template <> inline bool
|
||||
PatchTable::IsLocalPointVaryingStencilPrecision<double>() const {
|
||||
return _varyingPrecisionIsDouble;
|
||||
}
|
||||
template <> inline bool
|
||||
PatchTable::IsLocalPointFaceVaryingStencilPrecision<double>() const {
|
||||
return _faceVaryingPrecisionIsDouble;
|
||||
}
|
||||
|
||||
//
|
||||
// StencilTable access -- backward compatible and generic:
|
||||
//
|
||||
inline StencilTable const *
|
||||
PatchTable::GetLocalPointStencilTable() const {
|
||||
assert(!_vertexPrecisionIsDouble);
|
||||
return static_cast<StencilTable const *>(_localPointStencils.Get<float>());
|
||||
}
|
||||
inline StencilTable const *
|
||||
PatchTable::GetLocalPointVaryingStencilTable() const {
|
||||
assert(!_varyingPrecisionIsDouble);
|
||||
return static_cast<StencilTable const *>(
|
||||
_localPointVaryingStencils.Get<float>());
|
||||
}
|
||||
inline StencilTable const *
|
||||
PatchTable::GetLocalPointFaceVaryingStencilTable(int channel) const {
|
||||
assert(!_faceVaryingPrecisionIsDouble);
|
||||
if (channel >= 0 && channel < (int)_localPointFaceVaryingStencils.size()) {
|
||||
return static_cast<StencilTable const *>(
|
||||
_localPointFaceVaryingStencils[channel].Get<float>());
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
template <typename REAL>
|
||||
inline StencilTableReal<REAL> const *
|
||||
PatchTable::GetLocalPointStencilTable() const {
|
||||
assert(IsLocalPointStencilPrecision<REAL>());
|
||||
return _localPointStencils.Get<REAL>();
|
||||
}
|
||||
template <typename REAL>
|
||||
inline StencilTableReal<REAL> const *
|
||||
PatchTable::GetLocalPointVaryingStencilTable() const {
|
||||
assert(IsLocalPointVaryingStencilPrecision<REAL>());
|
||||
return _localPointVaryingStencils.Get<REAL>();
|
||||
}
|
||||
template <typename REAL>
|
||||
inline StencilTableReal<REAL> const *
|
||||
PatchTable::GetLocalPointFaceVaryingStencilTable(int channel) const {
|
||||
assert(IsLocalPointFaceVaryingStencilPrecision<REAL>());
|
||||
if (channel >= 0 && channel < (int)_localPointFaceVaryingStencils.size()) {
|
||||
return _localPointFaceVaryingStencils[channel].Get<REAL>();
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Computation of local point values:
|
||||
//
|
||||
template <class T>
|
||||
inline void
|
||||
PatchTable::ComputeLocalPointValues(T const *src, T *dst) const {
|
||||
if (_localPointStencils) {
|
||||
_localPointStencils->UpdateValues(src, dst);
|
||||
if (_localPointStencils.IsSet()) {
|
||||
if (_vertexPrecisionIsDouble) {
|
||||
_localPointStencils.Get<double>()->UpdateValues(src, dst);
|
||||
} else {
|
||||
_localPointStencils.Get<float>()->UpdateValues(src, dst);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void
|
||||
PatchTable::ComputeLocalPointValuesVarying(T const *src, T *dst) const {
|
||||
if (_localPointVaryingStencils) {
|
||||
_localPointVaryingStencils->UpdateValues(src, dst);
|
||||
if (_localPointVaryingStencils.IsSet()) {
|
||||
if (_varyingPrecisionIsDouble) {
|
||||
_localPointVaryingStencils.Get<double>()->UpdateValues(src, dst);
|
||||
} else {
|
||||
_localPointVaryingStencils.Get<float>()->UpdateValues(src, dst);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -629,12 +798,17 @@ template <class T>
|
||||
inline void
|
||||
PatchTable::ComputeLocalPointValuesFaceVarying(T const *src, T *dst, int channel) const {
|
||||
if (channel >= 0 && channel < (int)_localPointFaceVaryingStencils.size()) {
|
||||
if (_localPointFaceVaryingStencils[channel]) {
|
||||
_localPointFaceVaryingStencils[channel]->UpdateValues(src, dst);
|
||||
if (_localPointFaceVaryingStencils[channel].IsSet()) {
|
||||
if (_faceVaryingPrecisionIsDouble) {
|
||||
_localPointFaceVaryingStencils[channel].Get<double>()->UpdateValues(src, dst);
|
||||
} else {
|
||||
_localPointFaceVaryingStencils[channel].Get<float>()->UpdateValues(src, dst);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Basis evaluation overloads
|
||||
//
|
||||
|
@ -112,6 +112,8 @@ public:
|
||||
PatchTable * GetPatchTable() const { return _table; };
|
||||
|
||||
private:
|
||||
typedef PatchTable::StencilTableHandler StencilTableHandler;
|
||||
|
||||
// Simple struct to store <face,level> pair for a patch:
|
||||
struct PatchTuple {
|
||||
PatchTuple(Index face, int level) : faceIndex(face), levelIndex(level) { }
|
||||
@ -135,7 +137,8 @@ private:
|
||||
Level::VSpan irregCornerSpans[4];
|
||||
int paramBoundaryMask;
|
||||
|
||||
SparseMatrix<float> matrix;
|
||||
SparseMatrix<float> fMatrix;
|
||||
SparseMatrix<double> dMatrix;
|
||||
};
|
||||
|
||||
private:
|
||||
@ -161,12 +164,14 @@ private:
|
||||
Options() : shareLocalPoints(false),
|
||||
reuseSourcePoints(false),
|
||||
createStencilTable(true),
|
||||
createVaryingTable(false) { }
|
||||
createVaryingTable(false),
|
||||
doubleStencilTable(false) { }
|
||||
|
||||
unsigned int shareLocalPoints : 1;
|
||||
unsigned int reuseSourcePoints : 1;
|
||||
unsigned int createStencilTable : 1;
|
||||
unsigned int createVaryingTable : 1;
|
||||
unsigned int doubleStencilTable : 1;
|
||||
};
|
||||
|
||||
public:
|
||||
@ -179,36 +184,40 @@ private:
|
||||
public:
|
||||
int GetNumLocalPoints() const { return _numLocalPoints; }
|
||||
|
||||
template <typename REAL>
|
||||
int AppendLocalPatchPoints(int levelIndex, Index faceIndex,
|
||||
SparseMatrix<float> const & conversionMatrix,
|
||||
SparseMatrix<REAL> const & conversionMatrix,
|
||||
PatchDescriptor::Type patchType,
|
||||
Index const sourcePoints[],
|
||||
int sourcePointOffset,
|
||||
Index patchPoints[]);
|
||||
|
||||
StencilTable * AcquireStencilTable() {
|
||||
return acquireStencilTable(&_stencilTable);
|
||||
StencilTableHandler AcquireStencilTable() {
|
||||
return acquireStencilTable(_stencilTable);
|
||||
}
|
||||
|
||||
private:
|
||||
// Internal methods:
|
||||
void appendLocalPointStencil(SparseMatrix<float> const & conversionMatrix,
|
||||
template <typename REAL>
|
||||
void appendLocalPointStencil(SparseMatrix<REAL> const & conversionMatrix,
|
||||
int stencilRow,
|
||||
Index const sourcePoints[],
|
||||
int sourcePointOffset);
|
||||
|
||||
void appendLocalPointStencils(SparseMatrix<float> const & conversionMatrix,
|
||||
template <typename REAL>
|
||||
void appendLocalPointStencils(SparseMatrix<REAL> const & conversionMatrix,
|
||||
Index const sourcePoints[],
|
||||
int sourcePointOffset);
|
||||
|
||||
// Methods for local point Varying stencils
|
||||
// XXXX -- hope to get rid of these...
|
||||
template <typename REAL>
|
||||
void appendLocalPointVaryingStencil(int const * varyingIndices,
|
||||
int patchPointIndex,
|
||||
Index const sourcePoints[],
|
||||
int sourcePointOffset);
|
||||
|
||||
StencilTable * acquireStencilTable(StencilTable **stencilTableMember);
|
||||
StencilTableHandler acquireStencilTable(StencilTableHandler& stencilTableMember);
|
||||
|
||||
Index findSharedCornerPoint(int levelIndex, Index valueIndex,
|
||||
Index newIndex);
|
||||
@ -227,16 +236,16 @@ private:
|
||||
std::vector<IndexVector> _sharedCornerPoints;
|
||||
std::vector<IndexVector> _sharedEdgePoints;
|
||||
|
||||
StencilTable * _stencilTable;
|
||||
StencilTableHandler _stencilTable;
|
||||
|
||||
// This was hopefully transitional but will persist -- the should be
|
||||
// no need for Varying local points or stencils associated with them.
|
||||
public:
|
||||
StencilTable * AcquireStencilTableVarying() {
|
||||
return acquireStencilTable(&_stencilTableVarying);
|
||||
StencilTableHandler AcquireStencilTableVarying() {
|
||||
return acquireStencilTable(_stencilTableVarying);
|
||||
}
|
||||
|
||||
StencilTable * _stencilTableVarying;
|
||||
StencilTableHandler _stencilTableVarying;
|
||||
};
|
||||
|
||||
private:
|
||||
@ -428,6 +437,10 @@ PatchTableBuilder::PatchTableBuilder(
|
||||
|
||||
_table->_numPtexFaces = _ptexIndices.GetNumFaces();
|
||||
|
||||
_table->_vertexPrecisionIsDouble = _options.setPatchPrecisionDouble;
|
||||
_table->_varyingPrecisionIsDouble = _options.setPatchPrecisionDouble;
|
||||
_table->_faceVaryingPrecisionIsDouble = _options.setFVarPatchPrecisionDouble;
|
||||
|
||||
// State and helper to support LegacyGregory arrays in the PatchTable:
|
||||
_requiresLegacyGregoryTables = !_refiner.IsUniform() &&
|
||||
(_options.GetEndCapType() == Options::ENDCAP_LEGACY_GREGORY);
|
||||
@ -457,6 +470,10 @@ PatchTableBuilder::identifyPatchTopology(PatchTuple const & patch,
|
||||
patchInfo.isRegular = _patchBuilder->IsPatchRegular(
|
||||
patchLevel, patchFace, fvarInTable);
|
||||
|
||||
bool useDoubleMatrix = (fvarInRefiner < 0)
|
||||
? _options.setPatchPrecisionDouble
|
||||
: _options.setFVarPatchPrecisionDouble;
|
||||
|
||||
if (patchInfo.isRegular) {
|
||||
patchInfo.regBoundaryMask = _patchBuilder->GetRegularPatchBoundaryMask(
|
||||
patchLevel, patchFace, fvarInRefiner);
|
||||
@ -467,7 +484,7 @@ PatchTableBuilder::identifyPatchTopology(PatchTuple const & patch,
|
||||
|
||||
// If converting to another basis, get the change-of-basis matrix:
|
||||
if (_requiresRegularLocalPoints) {
|
||||
// _patchBuilder->GetRegularConversionMatrix(... patchInfo.matrix);
|
||||
// _patchBuilder->GetRegularConversionMatrix(...);
|
||||
}
|
||||
|
||||
//
|
||||
@ -501,8 +518,13 @@ PatchTableBuilder::identifyPatchTopology(PatchTuple const & patch,
|
||||
_patchBuilder->GetIrregularPatchCornerSpans(
|
||||
patchLevel, patchFace, patchInfo.irregCornerSpans, fvarInRefiner);
|
||||
|
||||
_patchBuilder->GetIrregularPatchConversionMatrix(
|
||||
patchLevel, patchFace, patchInfo.irregCornerSpans, patchInfo.matrix);
|
||||
if (useDoubleMatrix) {
|
||||
_patchBuilder->GetIrregularPatchConversionMatrix(
|
||||
patchLevel, patchFace, patchInfo.irregCornerSpans, patchInfo.dMatrix);
|
||||
} else {
|
||||
_patchBuilder->GetIrregularPatchConversionMatrix(
|
||||
patchLevel, patchFace, patchInfo.irregCornerSpans, patchInfo.fMatrix);
|
||||
}
|
||||
|
||||
patchInfo.paramBoundaryMask = 0;
|
||||
}
|
||||
@ -539,6 +561,10 @@ PatchTableBuilder::assignPatchPointsAndStencils(PatchTuple const & patch,
|
||||
? _levelVertOffsets[patch.levelIndex]
|
||||
: _levelFVarValueOffsets[fvarInTable][patch.levelIndex];
|
||||
|
||||
bool useDoubleMatrix = (fvarInTable < 0)
|
||||
? _options.setPatchPrecisionDouble
|
||||
: _options.setFVarPatchPrecisionDouble;
|
||||
|
||||
int numPatchPoints = 0;
|
||||
if (patchInfo.isRegular) {
|
||||
if (!_requiresRegularLocalPoints) {
|
||||
@ -571,18 +597,32 @@ PatchTableBuilder::assignPatchPointsAndStencils(PatchTuple const & patch,
|
||||
*/
|
||||
}
|
||||
} else if (_requiresIrregularLocalPoints) {
|
||||
StackBuffer<Index,64,true> sourcePoints(patchInfo.matrix.GetNumColumns());
|
||||
int numSourcePoints = 0;
|
||||
if (useDoubleMatrix) {
|
||||
numSourcePoints = patchInfo.dMatrix.GetNumColumns();
|
||||
numPatchPoints = patchInfo.dMatrix.GetNumRows();
|
||||
} else {
|
||||
numSourcePoints = patchInfo.fMatrix.GetNumColumns();
|
||||
numPatchPoints = patchInfo.fMatrix.GetNumRows();
|
||||
}
|
||||
|
||||
StackBuffer<Index,64,true> sourcePoints(numSourcePoints);
|
||||
|
||||
_patchBuilder->GetIrregularPatchSourcePoints(
|
||||
patch.levelIndex, patch.faceIndex,
|
||||
patchInfo.irregCornerSpans, sourcePoints, fvarInRefiner);
|
||||
|
||||
localHelper.AppendLocalPatchPoints(
|
||||
patch.levelIndex, patch.faceIndex,
|
||||
patchInfo.matrix, _patchBuilder->GetIrregularPatchType(),
|
||||
sourcePoints, sourcePointOffset, patchPoints);
|
||||
|
||||
numPatchPoints = patchInfo.matrix.GetNumRows();
|
||||
if (useDoubleMatrix) {
|
||||
localHelper.AppendLocalPatchPoints(
|
||||
patch.levelIndex, patch.faceIndex,
|
||||
patchInfo.dMatrix, _patchBuilder->GetIrregularPatchType(),
|
||||
sourcePoints, sourcePointOffset, patchPoints);
|
||||
} else {
|
||||
localHelper.AppendLocalPatchPoints(
|
||||
patch.levelIndex, patch.faceIndex,
|
||||
patchInfo.fMatrix, _patchBuilder->GetIrregularPatchType(),
|
||||
sourcePoints, sourcePointOffset, patchPoints);
|
||||
}
|
||||
}
|
||||
return numPatchPoints;
|
||||
}
|
||||
@ -1052,6 +1092,7 @@ PatchTableBuilder::populateAdaptivePatches() {
|
||||
LocalPointHelper::Options opts;
|
||||
opts.createStencilTable = true;
|
||||
opts.createVaryingTable = _requiresVaryingLocalPoints;
|
||||
opts.doubleStencilTable = _options.setPatchPrecisionDouble;
|
||||
opts.shareLocalPoints = _options.shareEndCapPatchPoints;
|
||||
opts.reuseSourcePoints = (_patchBuilder->GetIrregularPatchType() ==
|
||||
_patchBuilder->GetNativePatchType() );
|
||||
@ -1062,6 +1103,7 @@ PatchTableBuilder::populateAdaptivePatches() {
|
||||
if (_requiresFVarPatches) {
|
||||
opts.createStencilTable = true;
|
||||
opts.createVaryingTable = false;
|
||||
opts.doubleStencilTable = _options.setFVarPatchPrecisionDouble;
|
||||
|
||||
fvarLocalPointHelpers.SetSize((int)_fvarChannelIndices.size());
|
||||
|
||||
@ -1081,6 +1123,9 @@ PatchTableBuilder::populateAdaptivePatches() {
|
||||
PatchInfo patchInfo;
|
||||
PatchInfo fvarPatchInfo;
|
||||
|
||||
bool fvarPrecisionMatches = (_options.setPatchPrecisionDouble ==
|
||||
_options.setFVarPatchPrecisionDouble);
|
||||
|
||||
for (int patchIndex = 0; patchIndex < (int)_patches.size(); ++patchIndex) {
|
||||
|
||||
PatchTuple const & patch = _patches[patchIndex];
|
||||
@ -1138,7 +1183,8 @@ PatchTableBuilder::populateAdaptivePatches() {
|
||||
// topology of the face in face-varying space matches the
|
||||
// original patch:
|
||||
//
|
||||
bool fvcTopologyMatches = doesFVarTopologyMatch(patch, fvc);
|
||||
bool fvcTopologyMatches = fvarPrecisionMatches &&
|
||||
doesFVarTopologyMatch(patch, fvc);
|
||||
|
||||
PatchInfo & fvcPatchInfo = fvcTopologyMatches
|
||||
? patchInfo : fvarPatchInfo;
|
||||
@ -1298,16 +1344,23 @@ PatchTableBuilder::LocalPointHelper::LocalPointHelper(
|
||||
TopologyRefiner const & refiner, Options const & options,
|
||||
int fvarChannel, int numLocalPointsExpected) :
|
||||
_refiner(refiner), _options(options), _fvarChannel(fvarChannel),
|
||||
_numLocalPoints(0), _stencilTable(0), _stencilTableVarying(0) {
|
||||
_numLocalPoints(0), _stencilTable(), _stencilTableVarying() {
|
||||
|
||||
_localPointOffset = (_fvarChannel < 0)
|
||||
? _refiner.GetNumVerticesTotal()
|
||||
: _refiner.GetNumFVarValuesTotal(_fvarChannel);
|
||||
|
||||
if (_options.createStencilTable) {
|
||||
_stencilTable = new StencilTable(0);
|
||||
if (_options.createVaryingTable) {
|
||||
_stencilTableVarying = new StencilTable(0);
|
||||
if (_options.doubleStencilTable) {
|
||||
_stencilTable.Set(new StencilTableReal<double>(0));
|
||||
if (_options.createVaryingTable) {
|
||||
_stencilTableVarying.Set(new StencilTableReal<double>(0));
|
||||
}
|
||||
} else {
|
||||
_stencilTable.Set(new StencilTableReal<float>(0));
|
||||
if (_options.createVaryingTable) {
|
||||
_stencilTableVarying.Set(new StencilTableReal<float>(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1320,7 +1373,7 @@ PatchTableBuilder::LocalPointHelper::LocalPointHelper(
|
||||
// The average number of entries per stencil has been historically set
|
||||
// at 16, which seemed high and was reduced on further investigation.
|
||||
//
|
||||
if (_stencilTable) {
|
||||
if (_stencilTable.IsSet()) {
|
||||
// Historic note: limits to 100M (=800M bytes) entries for reserved size
|
||||
size_t const MaxEntriesToReserve = 100 * 1024 * 1024;
|
||||
size_t const AvgEntriesPerStencil = 9; // originally 16
|
||||
@ -1331,37 +1384,54 @@ PatchTableBuilder::LocalPointHelper::LocalPointHelper(
|
||||
size_t numEntriesToReserve = std::min(numStencilEntriesExpected,
|
||||
MaxEntriesToReserve);
|
||||
if (numEntriesToReserve) {
|
||||
_stencilTable->reserve((int)numStencilsExpected,
|
||||
(int)numEntriesToReserve);
|
||||
if (_stencilTableVarying) {
|
||||
if (_stencilTable.IsDouble()) {
|
||||
_stencilTable.Get<double>()->reserve(
|
||||
(int)numStencilsExpected, (int)numEntriesToReserve);
|
||||
} else {
|
||||
_stencilTable.Get<float>()->reserve(
|
||||
(int)numStencilsExpected, (int)numEntriesToReserve);
|
||||
}
|
||||
if (_stencilTableVarying.IsSet()) {
|
||||
// Varying stencils have only one entry per point
|
||||
_stencilTableVarying->reserve((int)numStencilsExpected,
|
||||
(int)numStencilsExpected);
|
||||
if (_stencilTableVarying.IsDouble()) {
|
||||
_stencilTableVarying.Get<double>()->reserve(
|
||||
(int)numStencilsExpected, (int)numStencilsExpected);
|
||||
} else {
|
||||
_stencilTableVarying.Get<float>()->reserve(
|
||||
(int)numStencilsExpected, (int)numStencilsExpected);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StencilTable *
|
||||
PatchTableBuilder::StencilTableHandler
|
||||
PatchTableBuilder::LocalPointHelper::acquireStencilTable(
|
||||
StencilTable **stencilTableMember) {
|
||||
StencilTableHandler& stencilTableMember) {
|
||||
|
||||
StencilTable * stencilTable = *stencilTableMember;
|
||||
StencilTableHandler stencilTable = stencilTableMember;
|
||||
|
||||
if (stencilTable && (stencilTable->GetNumStencils() > 0)) {
|
||||
stencilTable->finalize();
|
||||
} else {
|
||||
delete stencilTable;
|
||||
stencilTable = 0;
|
||||
if (stencilTable.IsSet()) {
|
||||
if (stencilTable.Size() > 0) {
|
||||
if (stencilTable.IsDouble()) {
|
||||
stencilTable.Get<double>()->finalize();
|
||||
} else {
|
||||
stencilTable.Get<float>()->finalize();
|
||||
}
|
||||
} else {
|
||||
stencilTable.Delete();
|
||||
stencilTable.Clear();
|
||||
}
|
||||
}
|
||||
*stencilTableMember = 0;
|
||||
|
||||
stencilTableMember.Clear();
|
||||
return stencilTable;
|
||||
}
|
||||
|
||||
PatchTableBuilder::LocalPointHelper::~LocalPointHelper() {
|
||||
|
||||
delete _stencilTable;
|
||||
delete _stencilTableVarying;
|
||||
_stencilTable.Delete();
|
||||
_stencilTableVarying.Delete();
|
||||
}
|
||||
|
||||
Index
|
||||
@ -1412,28 +1482,32 @@ PatchTableBuilder::LocalPointHelper::findSharedEdgePoint(int levelIndex,
|
||||
return assignedIndex;
|
||||
}
|
||||
|
||||
template <typename REAL>
|
||||
void
|
||||
PatchTableBuilder::LocalPointHelper::appendLocalPointStencil(
|
||||
SparseMatrix<float> const & conversionMatrix,
|
||||
SparseMatrix<REAL> const & conversionMatrix,
|
||||
int stencilRow,
|
||||
Index const sourcePoints[],
|
||||
int sourcePointOffset) {
|
||||
|
||||
int stencilSize = conversionMatrix.GetRowSize(stencilRow);
|
||||
ConstArray<int> matrixColumns = conversionMatrix.GetRowColumns(stencilRow);
|
||||
ConstArray<float> matrixWeights = conversionMatrix.GetRowElements(stencilRow);
|
||||
ConstArray<REAL> matrixWeights = conversionMatrix.GetRowElements(stencilRow);
|
||||
|
||||
_stencilTable->_sizes.push_back(stencilSize);
|
||||
StencilTableReal<REAL>* stencilTable = _stencilTable.Get<REAL>();
|
||||
|
||||
stencilTable->_sizes.push_back(stencilSize);
|
||||
for (int i = 0; i < stencilSize; ++i) {
|
||||
_stencilTable->_weights.push_back(matrixWeights[i]);
|
||||
_stencilTable->_indices.push_back(
|
||||
stencilTable->_weights.push_back(matrixWeights[i]);
|
||||
stencilTable->_indices.push_back(
|
||||
sourcePoints[matrixColumns[i]] + sourcePointOffset);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename REAL>
|
||||
void
|
||||
PatchTableBuilder::LocalPointHelper::appendLocalPointStencils(
|
||||
SparseMatrix<float> const & conversionMatrix,
|
||||
SparseMatrix<REAL> const & conversionMatrix,
|
||||
Index const sourcePoints[],
|
||||
int sourcePointOffset) {
|
||||
|
||||
@ -1441,37 +1515,39 @@ PatchTableBuilder::LocalPointHelper::appendLocalPointStencils(
|
||||
// Resize the StencilTable members to accomodate all rows and elements from
|
||||
// the given set of points represented by the matrix
|
||||
//
|
||||
StencilTableReal<REAL>* stencilTable = _stencilTable.Get<REAL>();
|
||||
|
||||
int numNewStencils = conversionMatrix.GetNumRows();
|
||||
int numNewElements = conversionMatrix.GetNumElements();
|
||||
|
||||
size_t numOldStencils = _stencilTable->_sizes.size();
|
||||
size_t numOldElements = _stencilTable->_indices.size();
|
||||
size_t numOldStencils = stencilTable->_sizes.size();
|
||||
size_t numOldElements = stencilTable->_indices.size();
|
||||
|
||||
// Assign the sizes for the new stencils:
|
||||
_stencilTable->_sizes.resize(numOldStencils + numNewStencils);
|
||||
stencilTable->_sizes.resize(numOldStencils + numNewStencils);
|
||||
|
||||
int * newSizes = &_stencilTable->_sizes[numOldStencils];
|
||||
int * newSizes = &stencilTable->_sizes[numOldStencils];
|
||||
for (int i = 0; i < numNewStencils; ++i) {
|
||||
newSizes[i] = conversionMatrix.GetRowSize(i);
|
||||
}
|
||||
|
||||
// Assign remapped indices for the stencils:
|
||||
_stencilTable->_indices.resize(numOldElements + numNewElements);
|
||||
stencilTable->_indices.resize(numOldElements + numNewElements);
|
||||
|
||||
int const * mtxIndices = &conversionMatrix.GetColumns()[0];
|
||||
int * newIndices = &_stencilTable->_indices[numOldElements];
|
||||
int * newIndices = &stencilTable->_indices[numOldElements];
|
||||
|
||||
for (int i = 0; i < numNewElements; ++i) {
|
||||
newIndices[i] = sourcePoints[mtxIndices[i]] + sourcePointOffset;
|
||||
}
|
||||
|
||||
// Copy the stencil weights direct from the matrix elements:
|
||||
_stencilTable->_weights.resize(numOldElements + numNewElements);
|
||||
stencilTable->_weights.resize(numOldElements + numNewElements);
|
||||
|
||||
float const * mtxWeights = &conversionMatrix.GetElements()[0];
|
||||
float * newWeights = &_stencilTable->_weights[numOldElements];
|
||||
REAL const * mtxWeights = &conversionMatrix.GetElements()[0];
|
||||
REAL * newWeights = &stencilTable->_weights[numOldElements];
|
||||
|
||||
std::memcpy(newWeights, mtxWeights, numNewElements * sizeof(float));
|
||||
std::memcpy(newWeights, mtxWeights, numNewElements * sizeof(REAL));
|
||||
}
|
||||
|
||||
//
|
||||
@ -1505,6 +1581,7 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
template <typename REAL>
|
||||
void
|
||||
PatchTableBuilder::LocalPointHelper::appendLocalPointVaryingStencil(
|
||||
int const * varyingIndices, int patchPointIndex,
|
||||
@ -1513,9 +1590,11 @@ PatchTableBuilder::LocalPointHelper::appendLocalPointVaryingStencil(
|
||||
Index varyingPoint =
|
||||
sourcePoints[varyingIndices[patchPointIndex]] + sourcePointOffset;
|
||||
|
||||
_stencilTableVarying->_sizes.push_back(1);
|
||||
_stencilTableVarying->_indices.push_back(varyingPoint);
|
||||
_stencilTableVarying->_weights.push_back(1.0f);
|
||||
StencilTableReal<REAL>* t = _stencilTableVarying.Get<REAL>();
|
||||
|
||||
t->_sizes.push_back(1);
|
||||
t->_indices.push_back(varyingPoint);
|
||||
t->_weights.push_back((REAL) 1.0);
|
||||
}
|
||||
|
||||
namespace {
|
||||
@ -1547,10 +1626,11 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
template <typename REAL>
|
||||
int
|
||||
PatchTableBuilder::LocalPointHelper::AppendLocalPatchPoints(
|
||||
int levelIndex, Index faceIndex,
|
||||
SparseMatrix<float> const & matrix,
|
||||
SparseMatrix<REAL> const & matrix,
|
||||
PatchDescriptor::Type patchType,
|
||||
Index const sourcePoints[],
|
||||
int sourcePointOffset,
|
||||
@ -1571,11 +1651,11 @@ PatchTableBuilder::LocalPointHelper::AppendLocalPatchPoints(
|
||||
bool shareLocalPointsForThisPatch = (shareBitsPerPoint != 0);
|
||||
|
||||
int const * varyingIndices = 0;
|
||||
if (_stencilTableVarying) {
|
||||
if (_stencilTableVarying.IsSet()) {
|
||||
varyingIndices = GetVaryingIndicesPerType(patchType);
|
||||
}
|
||||
|
||||
bool applyVertexStencils = (_stencilTable != 0);
|
||||
bool applyVertexStencils = _stencilTable.IsSet();
|
||||
bool applyVaryingStencils = (varyingIndices != 0);
|
||||
|
||||
//
|
||||
@ -1592,7 +1672,7 @@ PatchTableBuilder::LocalPointHelper::AppendLocalPatchPoints(
|
||||
matrix, sourcePoints, sourcePointOffset);
|
||||
if (applyVaryingStencils) {
|
||||
for (int i = 0; i < numPatchPoints; ++i) {
|
||||
appendLocalPointVaryingStencil(
|
||||
appendLocalPointVaryingStencil<REAL>(
|
||||
varyingIndices, i, sourcePoints, sourcePointOffset);
|
||||
}
|
||||
}
|
||||
@ -1611,7 +1691,7 @@ PatchTableBuilder::LocalPointHelper::AppendLocalPatchPoints(
|
||||
appendLocalPointStencil(
|
||||
matrix, i, sourcePoints, sourcePointOffset);
|
||||
if (applyVaryingStencils) {
|
||||
appendLocalPointVaryingStencil(
|
||||
appendLocalPointVaryingStencil<REAL>(
|
||||
varyingIndices, i, sourcePoints, sourcePointOffset);
|
||||
}
|
||||
}
|
||||
@ -1682,7 +1762,7 @@ PatchTableBuilder::LocalPointHelper::AppendLocalPatchPoints(
|
||||
appendLocalPointStencil(
|
||||
matrix, i, sourcePoints, sourcePointOffset);
|
||||
if (applyVaryingStencils) {
|
||||
appendLocalPointVaryingStencil(
|
||||
appendLocalPointVaryingStencil<REAL>(
|
||||
varyingIndices, i, sourcePoints, sourcePointOffset);
|
||||
}
|
||||
}
|
||||
|
@ -63,6 +63,8 @@ public:
|
||||
endCapType(ENDCAP_GREGORY_BASIS),
|
||||
shareEndCapPatchPoints(true),
|
||||
generateFVarTables(false),
|
||||
setPatchPrecisionDouble(false),
|
||||
setFVarPatchPrecisionDouble(false),
|
||||
generateFVarLegacyLinearPatches(true),
|
||||
generateLegacySharpCornerPatches(true),
|
||||
numFVarChannels(-1),
|
||||
@ -75,6 +77,12 @@ public:
|
||||
/// \brief Set endcap patch type
|
||||
void SetEndCapType(EndCapType e) { endCapType = e; }
|
||||
|
||||
/// \brief Set precision of vertex patches
|
||||
template <typename REAL> void SetPatchPrecision();
|
||||
|
||||
/// \brief Set precision of face-varying patches
|
||||
template <typename REAL> void SetFVarPatchPrecision();
|
||||
|
||||
unsigned int generateAllLevels : 1, ///< Include levels from 'firstLevel' to 'maxLevel' (Uniform mode only)
|
||||
triangulateQuads : 1, ///< Triangulate 'QUADS' primitives (Uniform mode only)
|
||||
useSingleCreasePatch : 1, ///< Use single crease patch
|
||||
@ -89,6 +97,10 @@ public:
|
||||
// face-varying
|
||||
generateFVarTables : 1, ///< Generate face-varying patch tables
|
||||
|
||||
// precision
|
||||
setPatchPrecisionDouble : 1, ///< Generate double-precision stencils for vertex patches
|
||||
setFVarPatchPrecisionDouble : 1, ///< Generate double-precision stencils for face-varying patches
|
||||
|
||||
// legacy behaviors (default to true)
|
||||
generateFVarLegacyLinearPatches : 1, ///< Generate all linear face-varying patches (legacy)
|
||||
generateLegacySharpCornerPatches : 1; ///< Generate sharp regular patches at smooth corners (legacy)
|
||||
@ -154,6 +166,22 @@ public:
|
||||
typedef std::vector<PatchFaceTag> PatchTagVector;
|
||||
};
|
||||
|
||||
|
||||
template <> inline void PatchTableFactory::Options::SetPatchPrecision<float>() {
|
||||
setPatchPrecisionDouble = false;
|
||||
}
|
||||
template <> inline void PatchTableFactory::Options::SetFVarPatchPrecision<float>() {
|
||||
setFVarPatchPrecisionDouble = false;
|
||||
}
|
||||
|
||||
template <> inline void PatchTableFactory::Options::SetPatchPrecision<double>() {
|
||||
setPatchPrecisionDouble = true;
|
||||
}
|
||||
template <> inline void PatchTableFactory::Options::SetFVarPatchPrecision<double>() {
|
||||
setFVarPatchPrecisionDouble = true;
|
||||
}
|
||||
|
||||
|
||||
} // end namespace Far
|
||||
|
||||
} // end namespace OPENSUBDIV_VERSION
|
||||
|
@ -49,15 +49,15 @@ namespace OPENSUBDIV_VERSION {
|
||||
|
||||
namespace Far {
|
||||
|
||||
|
||||
///
|
||||
/// \brief Applies refinement operations to generic primvar data.
|
||||
///
|
||||
class PrimvarRefiner {
|
||||
template <typename REAL>
|
||||
class PrimvarRefinerReal {
|
||||
|
||||
public:
|
||||
PrimvarRefiner(TopologyRefiner const & refiner) : _refiner(refiner) { }
|
||||
~PrimvarRefiner() { }
|
||||
PrimvarRefinerReal(TopologyRefiner const & refiner) : _refiner(refiner) { }
|
||||
~PrimvarRefinerReal() { }
|
||||
|
||||
TopologyRefiner const & GetTopologyRefiner() const { return _refiner; }
|
||||
|
||||
@ -182,10 +182,11 @@ public:
|
||||
//@}
|
||||
|
||||
private:
|
||||
typedef REAL Weight;
|
||||
|
||||
// Non-copyable:
|
||||
PrimvarRefiner(PrimvarRefiner const & src) : _refiner(src._refiner) { }
|
||||
PrimvarRefiner & operator=(PrimvarRefiner const &) { return *this; }
|
||||
PrimvarRefinerReal(PrimvarRefinerReal const & src) : _refiner(src._refiner) { }
|
||||
PrimvarRefinerReal & operator=(PrimvarRefinerReal const &) { return *this; }
|
||||
|
||||
template <Sdc::SchemeType SCHEME, class T, class U> void interpFromFaces(int, T const &, U &) const;
|
||||
template <Sdc::SchemeType SCHEME, class T, class U> void interpFromEdges(int, T const &, U &) const;
|
||||
@ -202,7 +203,6 @@ private:
|
||||
void limitFVar(T const & src, U & dst, int channel) const;
|
||||
|
||||
private:
|
||||
|
||||
TopologyRefiner const & _refiner;
|
||||
|
||||
private:
|
||||
@ -211,7 +211,7 @@ private:
|
||||
//
|
||||
class Mask {
|
||||
public:
|
||||
typedef float Weight; // Also part of the expected interface
|
||||
typedef REAL Weight; // Also part of the expected interface
|
||||
|
||||
public:
|
||||
Mask(Weight* v, Weight* e, Weight* f) :
|
||||
@ -261,9 +261,10 @@ private:
|
||||
// use as a template parameter in subsequent implementation will be factored
|
||||
// out of a later release:
|
||||
//
|
||||
template <typename REAL>
|
||||
template <class T, class U>
|
||||
inline void
|
||||
PrimvarRefiner::Interpolate(int level, T const & src, U & dst) const {
|
||||
PrimvarRefinerReal<REAL>::Interpolate(int level, T const & src, U & dst) const {
|
||||
|
||||
assert(level>0 && level<=(int)_refiner._refinements.size());
|
||||
|
||||
@ -286,9 +287,10 @@ PrimvarRefiner::Interpolate(int level, T const & src, U & dst) const {
|
||||
}
|
||||
}
|
||||
|
||||
template <typename REAL>
|
||||
template <class T, class U>
|
||||
inline void
|
||||
PrimvarRefiner::InterpolateFaceVarying(int level, T const & src, U & dst, int channel) const {
|
||||
PrimvarRefinerReal<REAL>::InterpolateFaceVarying(int level, T const & src, U & dst, int channel) const {
|
||||
|
||||
assert(level>0 && level<=(int)_refiner._refinements.size());
|
||||
|
||||
@ -311,9 +313,10 @@ PrimvarRefiner::InterpolateFaceVarying(int level, T const & src, U & dst, int ch
|
||||
}
|
||||
}
|
||||
|
||||
template <typename REAL>
|
||||
template <class T, class U>
|
||||
inline void
|
||||
PrimvarRefiner::Limit(T const & src, U & dst) const {
|
||||
PrimvarRefinerReal<REAL>::Limit(T const & src, U & dst) const {
|
||||
|
||||
if (_refiner.getLevel(_refiner.GetMaxLevel()).getNumVertexEdgesTotal() == 0) {
|
||||
Error(FAR_RUNTIME_ERROR,
|
||||
@ -335,9 +338,10 @@ PrimvarRefiner::Limit(T const & src, U & dst) const {
|
||||
}
|
||||
}
|
||||
|
||||
template <typename REAL>
|
||||
template <class T, class U, class U1, class U2>
|
||||
inline void
|
||||
PrimvarRefiner::Limit(T const & src, U & dstPos, U1 & dstTan1, U2 & dstTan2) const {
|
||||
PrimvarRefinerReal<REAL>::Limit(T const & src, U & dstPos, U1 & dstTan1, U2 & dstTan2) const {
|
||||
|
||||
if (_refiner.getLevel(_refiner.GetMaxLevel()).getNumVertexEdgesTotal() == 0) {
|
||||
Error(FAR_RUNTIME_ERROR,
|
||||
@ -359,9 +363,10 @@ PrimvarRefiner::Limit(T const & src, U & dstPos, U1 & dstTan1, U2 & dstTan2) con
|
||||
}
|
||||
}
|
||||
|
||||
template <typename REAL>
|
||||
template <class T, class U>
|
||||
inline void
|
||||
PrimvarRefiner::LimitFaceVarying(T const & src, U & dst, int channel) const {
|
||||
PrimvarRefinerReal<REAL>::LimitFaceVarying(T const & src, U & dst, int channel) const {
|
||||
|
||||
if (_refiner.getLevel(_refiner.GetMaxLevel()).getNumVertexEdgesTotal() == 0) {
|
||||
Error(FAR_RUNTIME_ERROR,
|
||||
@ -383,9 +388,10 @@ PrimvarRefiner::LimitFaceVarying(T const & src, U & dst, int channel) const {
|
||||
}
|
||||
}
|
||||
|
||||
template <typename REAL>
|
||||
template <class T, class U>
|
||||
inline void
|
||||
PrimvarRefiner::InterpolateFaceUniform(int level, T const & src, U & dst) const {
|
||||
PrimvarRefinerReal<REAL>::InterpolateFaceUniform(int level, T const & src, U & dst) const {
|
||||
|
||||
assert(level>0 && level<=(int)_refiner._refinements.size());
|
||||
|
||||
@ -400,9 +406,10 @@ PrimvarRefiner::InterpolateFaceUniform(int level, T const & src, U & dst) const
|
||||
}
|
||||
}
|
||||
|
||||
template <typename REAL>
|
||||
template <class T, class U>
|
||||
inline void
|
||||
PrimvarRefiner::InterpolateVarying(int level, T const & src, U & dst) const {
|
||||
PrimvarRefinerReal<REAL>::InterpolateVarying(int level, T const & src, U & dst) const {
|
||||
|
||||
assert(level>0 && level<=(int)_refiner._refinements.size());
|
||||
|
||||
@ -423,7 +430,7 @@ PrimvarRefiner::InterpolateVarying(int level, T const & src, U & dst) const {
|
||||
// Apply the weights to the parent face's vertices:
|
||||
ConstIndexArray fVerts = parent.getFaceVertices(face);
|
||||
|
||||
float fVaryingWeight = 1.0f / (float) fVerts.size();
|
||||
Weight fVaryingWeight = 1.0f / (Weight) fVerts.size();
|
||||
|
||||
dst[cVert].Clear();
|
||||
for (int i = 0; i < fVerts.size(); ++i) {
|
||||
@ -462,9 +469,10 @@ PrimvarRefiner::InterpolateVarying(int level, T const & src, U & dst) const {
|
||||
// Internal implementation methods -- grouping vertices to be interpolated
|
||||
// based on the type of parent component from which they originated:
|
||||
//
|
||||
template <typename REAL>
|
||||
template <Sdc::SchemeType SCHEME, class T, class U>
|
||||
inline void
|
||||
PrimvarRefiner::interpFromFaces(int level, T const & src, U & dst) const {
|
||||
PrimvarRefinerReal<REAL>::interpFromFaces(int level, T const & src, U & dst) const {
|
||||
|
||||
Vtr::internal::Refinement const & refinement = _refiner.getRefinement(level-1);
|
||||
Vtr::internal::Level const & parent = refinement.parent();
|
||||
@ -473,7 +481,7 @@ PrimvarRefiner::interpFromFaces(int level, T const & src, U & dst) const {
|
||||
|
||||
Sdc::Scheme<SCHEME> scheme(_refiner._subdivOptions);
|
||||
|
||||
Vtr::internal::StackBuffer<float,16> fVertWeights(parent.getMaxValence());
|
||||
Vtr::internal::StackBuffer<Weight,16> fVertWeights(parent.getMaxValence());
|
||||
|
||||
for (int face = 0; face < parent.getNumFaces(); ++face) {
|
||||
|
||||
@ -499,9 +507,10 @@ PrimvarRefiner::interpFromFaces(int level, T const & src, U & dst) const {
|
||||
}
|
||||
}
|
||||
|
||||
template <typename REAL>
|
||||
template <Sdc::SchemeType SCHEME, class T, class U>
|
||||
inline void
|
||||
PrimvarRefiner::interpFromEdges(int level, T const & src, U & dst) const {
|
||||
PrimvarRefinerReal<REAL>::interpFromEdges(int level, T const & src, U & dst) const {
|
||||
|
||||
Vtr::internal::Refinement const & refinement = _refiner.getRefinement(level-1);
|
||||
Vtr::internal::Level const & parent = refinement.parent();
|
||||
@ -511,8 +520,8 @@ PrimvarRefiner::interpFromEdges(int level, T const & src, U & dst) const {
|
||||
|
||||
Vtr::internal::EdgeInterface eHood(parent);
|
||||
|
||||
float eVertWeights[2];
|
||||
Vtr::internal::StackBuffer<float,8> eFaceWeights(parent.getMaxEdgeFaces());
|
||||
Weight eVertWeights[2];
|
||||
Vtr::internal::StackBuffer<Weight,8> eFaceWeights(parent.getMaxEdgeFaces());
|
||||
|
||||
for (int edge = 0; edge < parent.getNumEdges(); ++edge) {
|
||||
|
||||
@ -568,9 +577,10 @@ PrimvarRefiner::interpFromEdges(int level, T const & src, U & dst) const {
|
||||
}
|
||||
}
|
||||
|
||||
template <typename REAL>
|
||||
template <Sdc::SchemeType SCHEME, class T, class U>
|
||||
inline void
|
||||
PrimvarRefiner::interpFromVerts(int level, T const & src, U & dst) const {
|
||||
PrimvarRefinerReal<REAL>::interpFromVerts(int level, T const & src, U & dst) const {
|
||||
|
||||
Vtr::internal::Refinement const & refinement = _refiner.getRefinement(level-1);
|
||||
Vtr::internal::Level const & parent = refinement.parent();
|
||||
@ -580,7 +590,7 @@ PrimvarRefiner::interpFromVerts(int level, T const & src, U & dst) const {
|
||||
|
||||
Vtr::internal::VertexInterface vHood(parent, child);
|
||||
|
||||
Vtr::internal::StackBuffer<float,32> weightBuffer(2*parent.getMaxValence());
|
||||
Vtr::internal::StackBuffer<Weight,32> weightBuffer(2*parent.getMaxValence());
|
||||
|
||||
for (int vert = 0; vert < parent.getNumVertices(); ++vert) {
|
||||
|
||||
@ -592,9 +602,9 @@ PrimvarRefiner::interpFromVerts(int level, T const & src, U & dst) const {
|
||||
ConstIndexArray vEdges = parent.getVertexEdges(vert),
|
||||
vFaces = parent.getVertexFaces(vert);
|
||||
|
||||
float vVertWeight,
|
||||
* vEdgeWeights = weightBuffer,
|
||||
* vFaceWeights = vEdgeWeights + vEdges.size();
|
||||
Weight vVertWeight,
|
||||
* vEdgeWeights = weightBuffer,
|
||||
* vFaceWeights = vEdgeWeights + vEdges.size();
|
||||
|
||||
Mask vMask(&vVertWeight, vEdgeWeights, vFaceWeights);
|
||||
|
||||
@ -641,9 +651,10 @@ PrimvarRefiner::interpFromVerts(int level, T const & src, U & dst) const {
|
||||
//
|
||||
// Internal face-varying implementation details:
|
||||
//
|
||||
template <typename REAL>
|
||||
template <Sdc::SchemeType SCHEME, class T, class U>
|
||||
inline void
|
||||
PrimvarRefiner::interpFVarFromFaces(int level, T const & src, U & dst, int channel) const {
|
||||
PrimvarRefinerReal<REAL>::interpFVarFromFaces(int level, T const & src, U & dst, int channel) const {
|
||||
|
||||
Vtr::internal::Refinement const & refinement = _refiner.getRefinement(level-1);
|
||||
|
||||
@ -657,7 +668,7 @@ PrimvarRefiner::interpFVarFromFaces(int level, T const & src, U & dst, int chann
|
||||
Vtr::internal::FVarLevel const & parentFVar = parentLevel.getFVarLevel(channel);
|
||||
Vtr::internal::FVarLevel const & childFVar = childLevel.getFVarLevel(channel);
|
||||
|
||||
Vtr::internal::StackBuffer<float,16> fValueWeights(parentLevel.getMaxValence());
|
||||
Vtr::internal::StackBuffer<Weight,16> fValueWeights(parentLevel.getMaxValence());
|
||||
|
||||
for (int face = 0; face < parentLevel.getNumFaces(); ++face) {
|
||||
|
||||
@ -689,9 +700,10 @@ PrimvarRefiner::interpFVarFromFaces(int level, T const & src, U & dst, int chann
|
||||
}
|
||||
}
|
||||
|
||||
template <typename REAL>
|
||||
template <Sdc::SchemeType SCHEME, class T, class U>
|
||||
inline void
|
||||
PrimvarRefiner::interpFVarFromEdges(int level, T const & src, U & dst, int channel) const {
|
||||
PrimvarRefinerReal<REAL>::interpFVarFromEdges(int level, T const & src, U & dst, int channel) const {
|
||||
|
||||
Vtr::internal::Refinement const & refinement = _refiner.getRefinement(level-1);
|
||||
|
||||
@ -708,8 +720,8 @@ PrimvarRefiner::interpFVarFromEdges(int level, T const & src, U & dst, int chann
|
||||
// Allocate and initialize (if linearly interpolated) interpolation weights for
|
||||
// the edge mask:
|
||||
//
|
||||
float eVertWeights[2];
|
||||
Vtr::internal::StackBuffer<float,8> eFaceWeights(parentLevel.getMaxEdgeFaces());
|
||||
Weight eVertWeights[2];
|
||||
Vtr::internal::StackBuffer<Weight,8> eFaceWeights(parentLevel.getMaxEdgeFaces());
|
||||
|
||||
Mask eMask(eVertWeights, 0, eFaceWeights);
|
||||
|
||||
@ -833,9 +845,10 @@ PrimvarRefiner::interpFVarFromEdges(int level, T const & src, U & dst, int chann
|
||||
}
|
||||
}
|
||||
|
||||
template <typename REAL>
|
||||
template <Sdc::SchemeType SCHEME, class T, class U>
|
||||
inline void
|
||||
PrimvarRefiner::interpFVarFromVerts(int level, T const & src, U & dst, int channel) const {
|
||||
PrimvarRefinerReal<REAL>::interpFVarFromVerts(int level, T const & src, U & dst, int channel) const {
|
||||
|
||||
Vtr::internal::Refinement const & refinement = _refiner.getRefinement(level-1);
|
||||
|
||||
@ -850,7 +863,7 @@ PrimvarRefiner::interpFVarFromVerts(int level, T const & src, U & dst, int chann
|
||||
|
||||
bool isLinearFVar = parentFVar.isLinear() || (_refiner._subdivType == Sdc::SCHEME_BILINEAR);
|
||||
|
||||
Vtr::internal::StackBuffer<float,32> weightBuffer(2*parentLevel.getMaxValence());
|
||||
Vtr::internal::StackBuffer<Weight,32> weightBuffer(2*parentLevel.getMaxValence());
|
||||
|
||||
Vtr::internal::StackBuffer<Vtr::Index,16> vEdgeValues(parentLevel.getMaxValence());
|
||||
|
||||
@ -881,9 +894,9 @@ PrimvarRefiner::interpFVarFromVerts(int level, T const & src, U & dst, int chann
|
||||
//
|
||||
ConstIndexArray vEdges = parentLevel.getVertexEdges(vert);
|
||||
|
||||
float vVertWeight;
|
||||
float * vEdgeWeights = weightBuffer;
|
||||
float * vFaceWeights = vEdgeWeights + vEdges.size();
|
||||
Weight vVertWeight;
|
||||
Weight * vEdgeWeights = weightBuffer;
|
||||
Weight * vFaceWeights = vEdgeWeights + vEdges.size();
|
||||
|
||||
Mask vMask(&vVertWeight, vEdgeWeights, vFaceWeights);
|
||||
|
||||
@ -974,8 +987,8 @@ PrimvarRefiner::interpFVarFromVerts(int level, T const & src, U & dst, int chann
|
||||
Index pEndValues[2];
|
||||
parentFVar.getVertexCreaseEndValues(vert, pSibling, pEndValues);
|
||||
|
||||
float vWeight = 0.75f;
|
||||
float eWeight = 0.125f;
|
||||
Weight vWeight = 0.75f;
|
||||
Weight eWeight = 0.125f;
|
||||
|
||||
//
|
||||
// If semi-sharp we need to apply fractional weighting -- if made sharp because
|
||||
@ -983,10 +996,10 @@ PrimvarRefiner::interpFVarFromVerts(int level, T const & src, U & dst, int chann
|
||||
// other sibling (should only occur when there are 2):
|
||||
//
|
||||
if (pValueTags[pSibling].isSemiSharp()) {
|
||||
float wCorner = pValueTags[pSibling].isDepSharp()
|
||||
Weight wCorner = pValueTags[pSibling].isDepSharp()
|
||||
? refineFVar.getFractionalWeight(vert, !pSibling, cVert, !cSibling)
|
||||
: refineFVar.getFractionalWeight(vert, pSibling, cVert, cSibling);
|
||||
float wCrease = 1.0f - wCorner;
|
||||
Weight wCrease = 1.0f - wCorner;
|
||||
|
||||
vWeight = wCrease * 0.75f + wCorner;
|
||||
eWeight = wCrease * 0.125f;
|
||||
@ -1000,9 +1013,10 @@ PrimvarRefiner::interpFVarFromVerts(int level, T const & src, U & dst, int chann
|
||||
}
|
||||
}
|
||||
|
||||
template <typename REAL>
|
||||
template <Sdc::SchemeType SCHEME, class T, class U, class U1, class U2>
|
||||
inline void
|
||||
PrimvarRefiner::limit(T const & src, U & dstPos, U1 * dstTan1Ptr, U2 * dstTan2Ptr) const {
|
||||
PrimvarRefinerReal<REAL>::limit(T const & src, U & dstPos, U1 * dstTan1Ptr, U2 * dstTan2Ptr) const {
|
||||
|
||||
Sdc::Scheme<SCHEME> scheme(_refiner._subdivOptions);
|
||||
|
||||
@ -1013,17 +1027,17 @@ PrimvarRefiner::limit(T const & src, U & dstPos, U1 * dstTan1Ptr, U2 * dstTan2Pt
|
||||
int numMasks = 1 + (hasTangents ? 2 : 0);
|
||||
|
||||
Vtr::internal::StackBuffer<Index,33> indexBuffer(maxWeightsPerMask);
|
||||
Vtr::internal::StackBuffer<float,99> weightBuffer(numMasks * maxWeightsPerMask);
|
||||
Vtr::internal::StackBuffer<Weight,99> weightBuffer(numMasks * maxWeightsPerMask);
|
||||
|
||||
float * vPosWeights = weightBuffer,
|
||||
* ePosWeights = vPosWeights + 1,
|
||||
* fPosWeights = ePosWeights + level.getMaxValence();
|
||||
float * vTan1Weights = vPosWeights + maxWeightsPerMask,
|
||||
* eTan1Weights = ePosWeights + maxWeightsPerMask,
|
||||
* fTan1Weights = fPosWeights + maxWeightsPerMask;
|
||||
float * vTan2Weights = vTan1Weights + maxWeightsPerMask,
|
||||
* eTan2Weights = eTan1Weights + maxWeightsPerMask,
|
||||
* fTan2Weights = fTan1Weights + maxWeightsPerMask;
|
||||
Weight * vPosWeights = weightBuffer,
|
||||
* ePosWeights = vPosWeights + 1,
|
||||
* fPosWeights = ePosWeights + level.getMaxValence();
|
||||
Weight * vTan1Weights = vPosWeights + maxWeightsPerMask,
|
||||
* eTan1Weights = ePosWeights + maxWeightsPerMask,
|
||||
* fTan1Weights = fPosWeights + maxWeightsPerMask;
|
||||
Weight * vTan2Weights = vTan1Weights + maxWeightsPerMask,
|
||||
* eTan2Weights = eTan1Weights + maxWeightsPerMask,
|
||||
* fTan2Weights = fTan1Weights + maxWeightsPerMask;
|
||||
|
||||
Mask posMask( vPosWeights, ePosWeights, fPosWeights);
|
||||
Mask tan1Mask(vTan1Weights, eTan1Weights, fTan1Weights);
|
||||
@ -1134,9 +1148,10 @@ PrimvarRefiner::limit(T const & src, U & dstPos, U1 * dstTan1Ptr, U2 * dstTan2Pt
|
||||
}
|
||||
}
|
||||
|
||||
template <typename REAL>
|
||||
template <Sdc::SchemeType SCHEME, class T, class U>
|
||||
inline void
|
||||
PrimvarRefiner::limitFVar(T const & src, U & dst, int channel) const {
|
||||
PrimvarRefinerReal<REAL>::limitFVar(T const & src, U & dst, int channel) const {
|
||||
|
||||
Sdc::Scheme<SCHEME> scheme(_refiner._subdivOptions);
|
||||
|
||||
@ -1145,7 +1160,7 @@ PrimvarRefiner::limitFVar(T const & src, U & dst, int channel) const {
|
||||
|
||||
int maxWeightsPerMask = 1 + 2 * level.getMaxValence();
|
||||
|
||||
Vtr::internal::StackBuffer<float,33> weightBuffer(maxWeightsPerMask);
|
||||
Vtr::internal::StackBuffer<Weight,33> weightBuffer(maxWeightsPerMask);
|
||||
Vtr::internal::StackBuffer<Index,16> vEdgeBuffer(level.getMaxValence());
|
||||
|
||||
// This is a bit obscure -- assign both parent and child as last level
|
||||
@ -1178,9 +1193,9 @@ PrimvarRefiner::limitFVar(T const & src, U & dst, int channel) const {
|
||||
|
||||
// Assign the mask weights to the common buffer and compute the mask:
|
||||
//
|
||||
float * vWeights = weightBuffer,
|
||||
* eWeights = vWeights + 1,
|
||||
* fWeights = eWeights + vEdges.size();
|
||||
Weight * vWeights = weightBuffer,
|
||||
* eWeights = vWeights + 1,
|
||||
* fWeights = eWeights + vEdges.size();
|
||||
|
||||
Mask vMask(vWeights, eWeights, fWeights);
|
||||
|
||||
@ -1242,6 +1257,12 @@ PrimvarRefiner::limitFVar(T const & src, U & dst, int channel) const {
|
||||
}
|
||||
}
|
||||
|
||||
class PrimvarRefiner : public PrimvarRefinerReal<float> {
|
||||
public:
|
||||
PrimvarRefiner(TopologyRefiner const & refiner)
|
||||
: PrimvarRefinerReal<float>(refiner) { }
|
||||
};
|
||||
|
||||
} // end namespace Far
|
||||
|
||||
} // end namespace OPENSUBDIV_VERSION
|
||||
|
@ -37,25 +37,27 @@ namespace {
|
||||
#pragma warning disable 1572
|
||||
#endif
|
||||
|
||||
inline bool isWeightZero(float w) { return (w == 0.0f); }
|
||||
template <typename REAL>
|
||||
inline bool isWeightZero(REAL w) { return (w == (REAL)0.0); }
|
||||
|
||||
#ifdef __INTEL_COMPILER
|
||||
#pragma warning (pop)
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename REAL>
|
||||
struct Point1stDerivWeight {
|
||||
float p;
|
||||
float du;
|
||||
float dv;
|
||||
REAL p;
|
||||
REAL du;
|
||||
REAL dv;
|
||||
|
||||
Point1stDerivWeight()
|
||||
: p(0.0f), du(0.0f), dv(0.0f)
|
||||
{ }
|
||||
Point1stDerivWeight(float w)
|
||||
Point1stDerivWeight(REAL w)
|
||||
: p(w), du(w), dv(w)
|
||||
{ }
|
||||
Point1stDerivWeight(float w, float wDu, float wDv)
|
||||
Point1stDerivWeight(REAL w, REAL wDu, REAL wDv)
|
||||
: p(w), du(wDu), dv(wDv)
|
||||
{ }
|
||||
|
||||
@ -74,22 +76,23 @@ struct Point1stDerivWeight {
|
||||
}
|
||||
};
|
||||
|
||||
template <typename REAL>
|
||||
struct Point2ndDerivWeight {
|
||||
float p;
|
||||
float du;
|
||||
float dv;
|
||||
float duu;
|
||||
float duv;
|
||||
float dvv;
|
||||
REAL p;
|
||||
REAL du;
|
||||
REAL dv;
|
||||
REAL duu;
|
||||
REAL duv;
|
||||
REAL dvv;
|
||||
|
||||
Point2ndDerivWeight()
|
||||
: p(0.0f), du(0.0f), dv(0.0f), duu(0.0f), duv(0.0f), dvv(0.0f)
|
||||
{ }
|
||||
Point2ndDerivWeight(float w)
|
||||
Point2ndDerivWeight(REAL w)
|
||||
: p(w), du(w), dv(w), duu(w), duv(w), dvv(w)
|
||||
{ }
|
||||
Point2ndDerivWeight(float w, float wDu, float wDv,
|
||||
float wDuu, float wDuv, float wDvv)
|
||||
Point2ndDerivWeight(REAL w, REAL wDu, REAL wDv,
|
||||
REAL wDuu, REAL wDuv, REAL wDvv)
|
||||
: p(w), du(wDu), dv(wDv), duu(wDuu), duv(wDuv), dvv(wDvv)
|
||||
{ }
|
||||
|
||||
@ -116,6 +119,7 @@ struct Point2ndDerivWeight {
|
||||
|
||||
/// Stencil table constructor set.
|
||||
///
|
||||
template <typename REAL>
|
||||
class WeightTable {
|
||||
public:
|
||||
WeightTable(int coarseVerts,
|
||||
@ -198,20 +202,20 @@ public:
|
||||
public:
|
||||
Point1stDerivAccumulator(WeightTable* tbl) : _tbl(tbl)
|
||||
{ }
|
||||
void PushBack(Point1stDerivWeight weight) {
|
||||
void PushBack(Point1stDerivWeight<REAL> weight) {
|
||||
_tbl->_weights.push_back(weight.p);
|
||||
_tbl->_duWeights.push_back(weight.du);
|
||||
_tbl->_dvWeights.push_back(weight.dv);
|
||||
}
|
||||
void Add(size_t i, Point1stDerivWeight weight) {
|
||||
void Add(size_t i, Point1stDerivWeight<REAL> weight) {
|
||||
_tbl->_weights[i] += weight.p;
|
||||
_tbl->_duWeights[i] += weight.du;
|
||||
_tbl->_dvWeights[i] += weight.dv;
|
||||
}
|
||||
Point1stDerivWeight Get(size_t index) {
|
||||
return Point1stDerivWeight(_tbl->_weights[index],
|
||||
_tbl->_duWeights[index],
|
||||
_tbl->_dvWeights[index]);
|
||||
Point1stDerivWeight<REAL> Get(size_t index) {
|
||||
return Point1stDerivWeight<REAL>(_tbl->_weights[index],
|
||||
_tbl->_duWeights[index],
|
||||
_tbl->_dvWeights[index]);
|
||||
}
|
||||
};
|
||||
Point1stDerivAccumulator GetPoint1stDerivAccumulator() {
|
||||
@ -223,7 +227,7 @@ public:
|
||||
public:
|
||||
Point2ndDerivAccumulator(WeightTable* tbl) : _tbl(tbl)
|
||||
{ }
|
||||
void PushBack(Point2ndDerivWeight weight) {
|
||||
void PushBack(Point2ndDerivWeight<REAL> weight) {
|
||||
_tbl->_weights.push_back(weight.p);
|
||||
_tbl->_duWeights.push_back(weight.du);
|
||||
_tbl->_dvWeights.push_back(weight.dv);
|
||||
@ -231,7 +235,7 @@ public:
|
||||
_tbl->_duvWeights.push_back(weight.duv);
|
||||
_tbl->_dvvWeights.push_back(weight.dvv);
|
||||
}
|
||||
void Add(size_t i, Point2ndDerivWeight weight) {
|
||||
void Add(size_t i, Point2ndDerivWeight<REAL> weight) {
|
||||
_tbl->_weights[i] += weight.p;
|
||||
_tbl->_duWeights[i] += weight.du;
|
||||
_tbl->_dvWeights[i] += weight.dv;
|
||||
@ -239,13 +243,13 @@ public:
|
||||
_tbl->_duvWeights[i] += weight.duv;
|
||||
_tbl->_dvvWeights[i] += weight.dvv;
|
||||
}
|
||||
Point2ndDerivWeight Get(size_t index) {
|
||||
return Point2ndDerivWeight(_tbl->_weights[index],
|
||||
_tbl->_duWeights[index],
|
||||
_tbl->_dvWeights[index],
|
||||
_tbl->_duuWeights[index],
|
||||
_tbl->_duvWeights[index],
|
||||
_tbl->_dvvWeights[index]);
|
||||
Point2ndDerivWeight<REAL> Get(size_t index) {
|
||||
return Point2ndDerivWeight<REAL>(_tbl->_weights[index],
|
||||
_tbl->_duWeights[index],
|
||||
_tbl->_dvWeights[index],
|
||||
_tbl->_duuWeights[index],
|
||||
_tbl->_duvWeights[index],
|
||||
_tbl->_dvvWeights[index]);
|
||||
}
|
||||
};
|
||||
Point2ndDerivAccumulator GetPoint2ndDerivAccumulator() {
|
||||
@ -257,13 +261,13 @@ public:
|
||||
public:
|
||||
ScalarAccumulator(WeightTable* tbl) : _tbl(tbl)
|
||||
{ }
|
||||
void PushBack(float weight) {
|
||||
void PushBack(REAL weight) {
|
||||
_tbl->_weights.push_back(weight);
|
||||
}
|
||||
void Add(size_t i, float w) {
|
||||
void Add(size_t i, REAL w) {
|
||||
_tbl->_weights[i] += w;
|
||||
}
|
||||
float Get(size_t index) {
|
||||
REAL Get(size_t index) {
|
||||
return _tbl->_weights[index];
|
||||
}
|
||||
};
|
||||
@ -280,22 +284,22 @@ public:
|
||||
std::vector<int> const&
|
||||
GetSources() const { return _sources; }
|
||||
|
||||
std::vector<float> const&
|
||||
std::vector<REAL> const&
|
||||
GetWeights() const { return _weights; }
|
||||
|
||||
std::vector<float> const&
|
||||
std::vector<REAL> const&
|
||||
GetDuWeights() const { return _duWeights; }
|
||||
|
||||
std::vector<float> const&
|
||||
std::vector<REAL> const&
|
||||
GetDvWeights() const { return _dvWeights; }
|
||||
|
||||
std::vector<float> const&
|
||||
std::vector<REAL> const&
|
||||
GetDuuWeights() const { return _duuWeights; }
|
||||
|
||||
std::vector<float> const&
|
||||
std::vector<REAL> const&
|
||||
GetDuvWeights() const { return _duvWeights; }
|
||||
|
||||
std::vector<float> const&
|
||||
std::vector<REAL> const&
|
||||
GetDvvWeights() const { return _dvvWeights; }
|
||||
|
||||
void SetCoarseVertCount(int numVerts) {
|
||||
@ -387,12 +391,12 @@ private:
|
||||
|
||||
// The actual stencil data.
|
||||
std::vector<int> _sources;
|
||||
std::vector<float> _weights;
|
||||
std::vector<float> _duWeights;
|
||||
std::vector<float> _dvWeights;
|
||||
std::vector<float> _duuWeights;
|
||||
std::vector<float> _duvWeights;
|
||||
std::vector<float> _dvvWeights;
|
||||
std::vector<REAL> _weights;
|
||||
std::vector<REAL> _duWeights;
|
||||
std::vector<REAL> _dvWeights;
|
||||
std::vector<REAL> _duuWeights;
|
||||
std::vector<REAL> _duvWeights;
|
||||
std::vector<REAL> _dvvWeights;
|
||||
|
||||
// Index data used to recover stencil-to-vertex mapping.
|
||||
std::vector<int> _indices;
|
||||
@ -405,29 +409,33 @@ private:
|
||||
bool _compactWeights;
|
||||
};
|
||||
|
||||
StencilBuilder::StencilBuilder(int coarseVertCount,
|
||||
template <typename REAL>
|
||||
StencilBuilder<REAL>::StencilBuilder(int coarseVertCount,
|
||||
bool genCtrlVertStencils,
|
||||
bool compactWeights)
|
||||
: _weightTable(new WeightTable(coarseVertCount,
|
||||
: _weightTable(new WeightTable<REAL>(coarseVertCount,
|
||||
genCtrlVertStencils,
|
||||
compactWeights))
|
||||
{
|
||||
}
|
||||
|
||||
StencilBuilder::~StencilBuilder()
|
||||
template <typename REAL>
|
||||
StencilBuilder<REAL>::~StencilBuilder()
|
||||
{
|
||||
delete _weightTable;
|
||||
}
|
||||
|
||||
template <typename REAL>
|
||||
size_t
|
||||
StencilBuilder::GetNumVerticesTotal() const
|
||||
StencilBuilder<REAL>::GetNumVerticesTotal() const
|
||||
{
|
||||
return _weightTable->GetWeights().size();
|
||||
}
|
||||
|
||||
|
||||
template <typename REAL>
|
||||
int
|
||||
StencilBuilder::GetNumVertsInStencil(size_t stencilIndex) const
|
||||
StencilBuilder<REAL>::GetNumVertsInStencil(size_t stencilIndex) const
|
||||
{
|
||||
if (stencilIndex > _weightTable->GetSizes().size() - 1)
|
||||
return 0;
|
||||
@ -435,59 +443,70 @@ StencilBuilder::GetNumVertsInStencil(size_t stencilIndex) const
|
||||
return (int)_weightTable->GetSizes()[stencilIndex];
|
||||
}
|
||||
|
||||
template <typename REAL>
|
||||
void
|
||||
StencilBuilder::SetCoarseVertCount(int numVerts)
|
||||
StencilBuilder<REAL>::SetCoarseVertCount(int numVerts)
|
||||
{
|
||||
_weightTable->SetCoarseVertCount(numVerts);
|
||||
}
|
||||
|
||||
template <typename REAL>
|
||||
std::vector<int> const&
|
||||
StencilBuilder::GetStencilOffsets() const {
|
||||
StencilBuilder<REAL>::GetStencilOffsets() const {
|
||||
return _weightTable->GetOffsets();
|
||||
}
|
||||
|
||||
template <typename REAL>
|
||||
std::vector<int> const&
|
||||
StencilBuilder::GetStencilSizes() const {
|
||||
StencilBuilder<REAL>::GetStencilSizes() const {
|
||||
return _weightTable->GetSizes();
|
||||
}
|
||||
|
||||
template <typename REAL>
|
||||
std::vector<int> const&
|
||||
StencilBuilder::GetStencilSources() const {
|
||||
StencilBuilder<REAL>::GetStencilSources() const {
|
||||
return _weightTable->GetSources();
|
||||
}
|
||||
|
||||
std::vector<float> const&
|
||||
StencilBuilder::GetStencilWeights() const {
|
||||
template <typename REAL>
|
||||
std::vector<REAL> const&
|
||||
StencilBuilder<REAL>::GetStencilWeights() const {
|
||||
return _weightTable->GetWeights();
|
||||
}
|
||||
|
||||
std::vector<float> const&
|
||||
StencilBuilder::GetStencilDuWeights() const {
|
||||
template <typename REAL>
|
||||
std::vector<REAL> const&
|
||||
StencilBuilder<REAL>::GetStencilDuWeights() const {
|
||||
return _weightTable->GetDuWeights();
|
||||
}
|
||||
|
||||
std::vector<float> const&
|
||||
StencilBuilder::GetStencilDvWeights() const {
|
||||
template <typename REAL>
|
||||
std::vector<REAL> const&
|
||||
StencilBuilder<REAL>::GetStencilDvWeights() const {
|
||||
return _weightTable->GetDvWeights();
|
||||
}
|
||||
|
||||
std::vector<float> const&
|
||||
StencilBuilder::GetStencilDuuWeights() const {
|
||||
template <typename REAL>
|
||||
std::vector<REAL> const&
|
||||
StencilBuilder<REAL>::GetStencilDuuWeights() const {
|
||||
return _weightTable->GetDuuWeights();
|
||||
}
|
||||
|
||||
std::vector<float> const&
|
||||
StencilBuilder::GetStencilDuvWeights() const {
|
||||
template <typename REAL>
|
||||
std::vector<REAL> const&
|
||||
StencilBuilder<REAL>::GetStencilDuvWeights() const {
|
||||
return _weightTable->GetDuvWeights();
|
||||
}
|
||||
|
||||
std::vector<float> const&
|
||||
StencilBuilder::GetStencilDvvWeights() const {
|
||||
template <typename REAL>
|
||||
std::vector<REAL> const&
|
||||
StencilBuilder<REAL>::GetStencilDvvWeights() const {
|
||||
return _weightTable->GetDvvWeights();
|
||||
}
|
||||
|
||||
template <typename REAL>
|
||||
void
|
||||
StencilBuilder::Index::AddWithWeight(Index const & src, float weight)
|
||||
StencilBuilder<REAL>::Index::AddWithWeight(Index const & src, REAL weight)
|
||||
{
|
||||
// Ignore no-op weights.
|
||||
if (isWeightZero(weight)) {
|
||||
@ -497,8 +516,9 @@ StencilBuilder::Index::AddWithWeight(Index const & src, float weight)
|
||||
_owner->_weightTable->GetScalarAccumulator());
|
||||
}
|
||||
|
||||
template <typename REAL>
|
||||
void
|
||||
StencilBuilder::Index::AddWithWeight(Stencil const& src, float weight)
|
||||
StencilBuilder<REAL>::Index::AddWithWeight(StencilReal<REAL> const& src, REAL weight)
|
||||
{
|
||||
if (isWeightZero(weight)) {
|
||||
return;
|
||||
@ -506,25 +526,26 @@ StencilBuilder::Index::AddWithWeight(Stencil const& src, float weight)
|
||||
|
||||
int srcSize = *src.GetSizePtr();
|
||||
Vtr::Index const * srcIndices = src.GetVertexIndices();
|
||||
float const * srcWeights = src.GetWeights();
|
||||
REAL const * srcWeights = src.GetWeights();
|
||||
|
||||
for (int i = 0; i < srcSize; ++i) {
|
||||
float w = srcWeights[i];
|
||||
REAL w = srcWeights[i];
|
||||
if (isWeightZero(w)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Vtr::Index srcIndex = srcIndices[i];
|
||||
|
||||
float wgt = weight * w;
|
||||
REAL wgt = weight * w;
|
||||
_owner->_weightTable->AddWithWeight(srcIndex, _index, wgt,
|
||||
_owner->_weightTable->GetScalarAccumulator());
|
||||
}
|
||||
}
|
||||
|
||||
template <typename REAL>
|
||||
void
|
||||
StencilBuilder::Index::AddWithWeight(Stencil const& src,
|
||||
float weight, float du, float dv)
|
||||
StencilBuilder<REAL>::Index::AddWithWeight(StencilReal<REAL> const& src,
|
||||
REAL weight, REAL du, REAL dv)
|
||||
{
|
||||
if (isWeightZero(weight) && isWeightZero(du) && isWeightZero(dv)) {
|
||||
return;
|
||||
@ -532,25 +553,26 @@ StencilBuilder::Index::AddWithWeight(Stencil const& src,
|
||||
|
||||
int srcSize = *src.GetSizePtr();
|
||||
Vtr::Index const * srcIndices = src.GetVertexIndices();
|
||||
float const * srcWeights = src.GetWeights();
|
||||
REAL const * srcWeights = src.GetWeights();
|
||||
|
||||
for (int i = 0; i < srcSize; ++i) {
|
||||
float w = srcWeights[i];
|
||||
REAL w = srcWeights[i];
|
||||
if (isWeightZero(w)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Vtr::Index srcIndex = srcIndices[i];
|
||||
|
||||
Point1stDerivWeight wgt = Point1stDerivWeight(weight, du, dv) * w;
|
||||
Point1stDerivWeight<REAL> wgt = Point1stDerivWeight<REAL>(weight, du, dv) * w;
|
||||
_owner->_weightTable->AddWithWeight(srcIndex, _index, wgt,
|
||||
_owner->_weightTable->GetPoint1stDerivAccumulator());
|
||||
}
|
||||
}
|
||||
|
||||
template <typename REAL>
|
||||
void
|
||||
StencilBuilder::Index::AddWithWeight(Stencil const& src,
|
||||
float weight, float du, float dv, float duu, float duv, float dvv)
|
||||
StencilBuilder<REAL>::Index::AddWithWeight(StencilReal<REAL> const& src,
|
||||
REAL weight, REAL du, REAL dv, REAL duu, REAL duv, REAL dvv)
|
||||
{
|
||||
if (isWeightZero(weight) && isWeightZero(du) && isWeightZero(dv) &&
|
||||
isWeightZero(duu) && isWeightZero(duv) && isWeightZero(dvv)) {
|
||||
@ -559,24 +581,26 @@ StencilBuilder::Index::AddWithWeight(Stencil const& src,
|
||||
|
||||
int srcSize = *src.GetSizePtr();
|
||||
Vtr::Index const * srcIndices = src.GetVertexIndices();
|
||||
float const * srcWeights = src.GetWeights();
|
||||
REAL const * srcWeights = src.GetWeights();
|
||||
|
||||
for (int i = 0; i < srcSize; ++i) {
|
||||
float w = srcWeights[i];
|
||||
REAL w = srcWeights[i];
|
||||
if (isWeightZero(w)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Vtr::Index srcIndex = srcIndices[i];
|
||||
|
||||
Point2ndDerivWeight wgt = Point2ndDerivWeight(weight, du, dv, duu, duv, dvv) * w;
|
||||
Point2ndDerivWeight<REAL> wgt = Point2ndDerivWeight<REAL>(weight, du, dv, duu, duv, dvv) * w;
|
||||
_owner->_weightTable->AddWithWeight(srcIndex, _index, wgt,
|
||||
_owner->_weightTable->GetPoint2ndDerivAccumulator());
|
||||
}
|
||||
}
|
||||
|
||||
template class StencilBuilder<float>;
|
||||
template class StencilBuilder<double>;
|
||||
|
||||
} // end namespace internal
|
||||
} // end namespace Far
|
||||
} // end namespace OPENSUBDIV_VERSION
|
||||
} // end namespace OpenSubdiv
|
||||
|
||||
|
@ -36,8 +36,9 @@ namespace OPENSUBDIV_VERSION {
|
||||
namespace Far {
|
||||
namespace internal {
|
||||
|
||||
class WeightTable;
|
||||
template <typename REAL> class WeightTable;
|
||||
|
||||
template <typename REAL>
|
||||
class StencilBuilder {
|
||||
public:
|
||||
StencilBuilder(int coarseVertCount,
|
||||
@ -63,12 +64,12 @@ public:
|
||||
std::vector<int> const& GetStencilSources() const;
|
||||
|
||||
// The individual vertex weights, each weight is paired with one source.
|
||||
std::vector<float> const& GetStencilWeights() const;
|
||||
std::vector<float> const& GetStencilDuWeights() const;
|
||||
std::vector<float> const& GetStencilDvWeights() const;
|
||||
std::vector<float> const& GetStencilDuuWeights() const;
|
||||
std::vector<float> const& GetStencilDuvWeights() const;
|
||||
std::vector<float> const& GetStencilDvvWeights() const;
|
||||
std::vector<REAL> const& GetStencilWeights() const;
|
||||
std::vector<REAL> const& GetStencilDuWeights() const;
|
||||
std::vector<REAL> const& GetStencilDvWeights() const;
|
||||
std::vector<REAL> const& GetStencilDuuWeights() const;
|
||||
std::vector<REAL> const& GetStencilDuvWeights() const;
|
||||
std::vector<REAL> const& GetStencilDvvWeights() const;
|
||||
|
||||
// Vertex Facade.
|
||||
class Index {
|
||||
@ -79,16 +80,16 @@ public:
|
||||
{}
|
||||
|
||||
// Add with point/vertex weight only.
|
||||
void AddWithWeight(Index const & src, float weight);
|
||||
void AddWithWeight(Stencil const& src, float weight);
|
||||
void AddWithWeight(Index const & src, REAL weight);
|
||||
void AddWithWeight(StencilReal<REAL> const& src, REAL weight);
|
||||
|
||||
// Add with first derivative.
|
||||
void AddWithWeight(Stencil const& src,
|
||||
float weight, float du, float dv);
|
||||
void AddWithWeight(StencilReal<REAL> const& src,
|
||||
REAL weight, REAL du, REAL dv);
|
||||
|
||||
// Add with first and second derivatives.
|
||||
void AddWithWeight(Stencil const& src,
|
||||
float weight, float du, float dv, float duu, float duv, float dvv);
|
||||
void AddWithWeight(StencilReal<REAL> const& src,
|
||||
REAL weight, REAL du, REAL dv, REAL duu, REAL duv, REAL dvv);
|
||||
|
||||
Index operator[](int index) const {
|
||||
return Index(_owner, index+_index);
|
||||
@ -103,7 +104,7 @@ public:
|
||||
};
|
||||
|
||||
private:
|
||||
WeightTable* _weightTable;
|
||||
WeightTable<REAL>* _weightTable;
|
||||
};
|
||||
|
||||
} // end namespace internal
|
||||
|
@ -32,28 +32,29 @@ namespace Far {
|
||||
|
||||
|
||||
namespace {
|
||||
template <typename REAL>
|
||||
void
|
||||
copyStencilData(int numControlVerts,
|
||||
bool includeCoarseVerts,
|
||||
size_t firstOffset,
|
||||
std::vector<int> const* offsets,
|
||||
std::vector<int> * _offsets,
|
||||
std::vector<int> const* sizes,
|
||||
std::vector<int> * _sizes,
|
||||
std::vector<int> const* sources,
|
||||
std::vector<int> * _sources,
|
||||
std::vector<float> const* weights,
|
||||
std::vector<float> * _weights,
|
||||
std::vector<float> const* duWeights=NULL,
|
||||
std::vector<float> * _duWeights=NULL,
|
||||
std::vector<float> const* dvWeights=NULL,
|
||||
std::vector<float> * _dvWeights=NULL,
|
||||
std::vector<float> const* duuWeights=NULL,
|
||||
std::vector<float> * _duuWeights=NULL,
|
||||
std::vector<float> const* duvWeights=NULL,
|
||||
std::vector<float> * _duvWeights=NULL,
|
||||
std::vector<float> const* dvvWeights=NULL,
|
||||
std::vector<float> * _dvvWeights=NULL) {
|
||||
std::vector<int> const* offsets,
|
||||
std::vector<int> * _offsets,
|
||||
std::vector<int> const* sizes,
|
||||
std::vector<int> * _sizes,
|
||||
std::vector<int> const* sources,
|
||||
std::vector<int> * _sources,
|
||||
std::vector<REAL> const* weights,
|
||||
std::vector<REAL> * _weights,
|
||||
std::vector<REAL> const* duWeights=NULL,
|
||||
std::vector<REAL> * _duWeights=NULL,
|
||||
std::vector<REAL> const* dvWeights=NULL,
|
||||
std::vector<REAL> * _dvWeights=NULL,
|
||||
std::vector<REAL> const* duuWeights=NULL,
|
||||
std::vector<REAL> * _duuWeights=NULL,
|
||||
std::vector<REAL> const* duvWeights=NULL,
|
||||
std::vector<REAL> * _duvWeights=NULL,
|
||||
std::vector<REAL> const* dvvWeights=NULL,
|
||||
std::vector<REAL> * _dvvWeights=NULL) {
|
||||
size_t start = includeCoarseVerts ? 0 : firstOffset;
|
||||
|
||||
_offsets->resize(offsets->size());
|
||||
@ -94,28 +95,28 @@ namespace {
|
||||
std::memcpy(&(*_sources)[curOffset],
|
||||
&(*sources)[off], sz*sizeof(int));
|
||||
std::memcpy(&(*_weights)[curOffset],
|
||||
&(*weights)[off], sz*sizeof(float));
|
||||
&(*weights)[off], sz*sizeof(REAL));
|
||||
|
||||
if (_duWeights && !_duWeights->empty()) {
|
||||
std::memcpy(&(*_duWeights)[curOffset],
|
||||
&(*duWeights)[off], sz*sizeof(float));
|
||||
&(*duWeights)[off], sz*sizeof(REAL));
|
||||
}
|
||||
if (_dvWeights && !_dvWeights->empty()) {
|
||||
std::memcpy(&(*_dvWeights)[curOffset],
|
||||
&(*dvWeights)[off], sz*sizeof(float));
|
||||
&(*dvWeights)[off], sz*sizeof(REAL));
|
||||
}
|
||||
|
||||
if (_duuWeights && !_duuWeights->empty()) {
|
||||
std::memcpy(&(*_duuWeights)[curOffset],
|
||||
&(*duuWeights)[off], sz*sizeof(float));
|
||||
&(*duuWeights)[off], sz*sizeof(REAL));
|
||||
}
|
||||
if (_duvWeights && !_duvWeights->empty()) {
|
||||
std::memcpy(&(*_duvWeights)[curOffset],
|
||||
&(*duvWeights)[off], sz*sizeof(float));
|
||||
&(*duvWeights)[off], sz*sizeof(REAL));
|
||||
}
|
||||
if (_dvvWeights && !_dvvWeights->empty()) {
|
||||
std::memcpy(&(*_dvvWeights)[curOffset],
|
||||
&(*dvvWeights)[off], sz*sizeof(float));
|
||||
&(*dvvWeights)[off], sz*sizeof(REAL));
|
||||
}
|
||||
|
||||
curOffset += sz;
|
||||
@ -141,11 +142,12 @@ namespace {
|
||||
}
|
||||
};
|
||||
|
||||
StencilTable::StencilTable(int numControlVerts,
|
||||
template <typename REAL>
|
||||
StencilTableReal<REAL>::StencilTableReal(int numControlVerts,
|
||||
std::vector<int> const& offsets,
|
||||
std::vector<int> const& sizes,
|
||||
std::vector<int> const& sources,
|
||||
std::vector<float> const& weights,
|
||||
std::vector<REAL> const& weights,
|
||||
bool includeCoarseVerts,
|
||||
size_t firstOffset)
|
||||
: _numControlVertices(numControlVerts) {
|
||||
@ -158,8 +160,9 @@ StencilTable::StencilTable(int numControlVerts,
|
||||
&weights, &_weights);
|
||||
}
|
||||
|
||||
template <typename REAL>
|
||||
void
|
||||
StencilTable::Clear() {
|
||||
StencilTableReal<REAL>::Clear() {
|
||||
_numControlVertices=0;
|
||||
_sizes.clear();
|
||||
_offsets.clear();
|
||||
@ -167,26 +170,28 @@ StencilTable::Clear() {
|
||||
_weights.clear();
|
||||
}
|
||||
|
||||
LimitStencilTable::LimitStencilTable(int numControlVerts,
|
||||
template <typename REAL>
|
||||
LimitStencilTableReal<REAL>::LimitStencilTableReal(
|
||||
int numControlVerts,
|
||||
std::vector<int> const& offsets,
|
||||
std::vector<int> const& sizes,
|
||||
std::vector<int> const& sources,
|
||||
std::vector<float> const& weights,
|
||||
std::vector<float> const& duWeights,
|
||||
std::vector<float> const& dvWeights,
|
||||
std::vector<float> const& duuWeights,
|
||||
std::vector<float> const& duvWeights,
|
||||
std::vector<float> const& dvvWeights,
|
||||
std::vector<REAL> const& weights,
|
||||
std::vector<REAL> const& duWeights,
|
||||
std::vector<REAL> const& dvWeights,
|
||||
std::vector<REAL> const& duuWeights,
|
||||
std::vector<REAL> const& duvWeights,
|
||||
std::vector<REAL> const& dvvWeights,
|
||||
bool includeCoarseVerts,
|
||||
size_t firstOffset)
|
||||
: StencilTable(numControlVerts) {
|
||||
: StencilTableReal<REAL>(numControlVerts) {
|
||||
copyStencilData(numControlVerts,
|
||||
includeCoarseVerts,
|
||||
firstOffset,
|
||||
&offsets, &_offsets,
|
||||
&sizes, &_sizes,
|
||||
&sources, &_indices,
|
||||
&weights, &_weights,
|
||||
&offsets, &this->_offsets,
|
||||
&sizes, &this->_sizes,
|
||||
&sources, &this->_indices,
|
||||
&weights, &this->_weights,
|
||||
&duWeights, &_duWeights,
|
||||
&dvWeights, &_dvWeights,
|
||||
&duuWeights, &_duuWeights,
|
||||
@ -194,9 +199,10 @@ LimitStencilTable::LimitStencilTable(int numControlVerts,
|
||||
&dvvWeights, &_dvvWeights);
|
||||
}
|
||||
|
||||
template <typename REAL>
|
||||
void
|
||||
LimitStencilTable::Clear() {
|
||||
StencilTable::Clear();
|
||||
LimitStencilTableReal<REAL>::Clear() {
|
||||
StencilTableReal<REAL>::Clear();
|
||||
_duWeights.clear();
|
||||
_dvWeights.clear();
|
||||
_duuWeights.clear();
|
||||
@ -205,11 +211,24 @@ LimitStencilTable::Clear() {
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Explicit instantiation for float and double:
|
||||
//
|
||||
template class StencilReal<float>;
|
||||
template class StencilReal<double>;
|
||||
|
||||
template class LimitStencilReal<float>;
|
||||
template class LimitStencilReal<double>;
|
||||
|
||||
template class StencilTableReal<float>;
|
||||
template class StencilTableReal<double>;
|
||||
|
||||
template class LimitStencilTableReal<float>;
|
||||
template class LimitStencilTableReal<double>;
|
||||
|
||||
} // end namespace Far
|
||||
|
||||
} // end namespace OPENSUBDIV_VERSION
|
||||
using namespace OPENSUBDIV_VERSION;
|
||||
|
||||
} // end namespace OpenSubdiv
|
||||
|
||||
|
||||
|
@ -39,16 +39,22 @@ namespace OPENSUBDIV_VERSION {
|
||||
|
||||
namespace Far {
|
||||
|
||||
// Forward declarations for friends:
|
||||
class PatchTableBuilder;
|
||||
|
||||
template <typename REAL> class StencilTableFactoryReal;
|
||||
template <typename REAL> class LimitStencilTableFactoryReal;
|
||||
|
||||
/// \brief Vertex stencil descriptor
|
||||
///
|
||||
/// Allows access and manipulation of a single stencil in a StencilTable.
|
||||
///
|
||||
class Stencil {
|
||||
|
||||
template <typename REAL>
|
||||
class StencilReal {
|
||||
public:
|
||||
|
||||
/// \brief Default constructor
|
||||
Stencil() {}
|
||||
StencilReal() {}
|
||||
|
||||
/// \brief Constructor
|
||||
///
|
||||
@ -58,16 +64,11 @@ public:
|
||||
///
|
||||
/// @param weights Table pointer to the vertex weights of the stencil
|
||||
///
|
||||
Stencil(int * size,
|
||||
Index * indices,
|
||||
float * weights)
|
||||
: _size(size),
|
||||
_indices(indices),
|
||||
_weights(weights) {
|
||||
}
|
||||
StencilReal(int * size, Index * indices, REAL * weights)
|
||||
: _size(size), _indices(indices), _weights(weights) { }
|
||||
|
||||
/// \brief Copy constructor
|
||||
Stencil(Stencil const & other) {
|
||||
StencilReal(StencilReal const & other) {
|
||||
_size = other._size;
|
||||
_indices = other._indices;
|
||||
_weights = other._weights;
|
||||
@ -89,7 +90,7 @@ public:
|
||||
}
|
||||
|
||||
/// \brief Returns the interpolation weights
|
||||
float const * GetWeights() const {
|
||||
REAL const * GetWeights() const {
|
||||
return _weights;
|
||||
}
|
||||
|
||||
@ -102,14 +103,28 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
friend class StencilTableFactory;
|
||||
friend class LimitStencilTableFactory;
|
||||
friend class StencilTableFactoryReal<REAL>;
|
||||
friend class LimitStencilTableFactoryReal<REAL>;
|
||||
|
||||
int * _size;
|
||||
Index * _indices;
|
||||
float * _weights;
|
||||
Index * _indices;
|
||||
REAL * _weights;
|
||||
};
|
||||
|
||||
/// \brief Vertex stencil class wrapping the template for compatibility.
|
||||
///
|
||||
class Stencil : public StencilReal<float> {
|
||||
protected:
|
||||
typedef StencilReal<float> BaseStencil;
|
||||
|
||||
public:
|
||||
Stencil() : BaseStencil() { }
|
||||
Stencil(BaseStencil const & other) : BaseStencil(other) { }
|
||||
Stencil(int * size, Index * indices, float * weights)
|
||||
: BaseStencil(size, indices, weights) { }
|
||||
};
|
||||
|
||||
|
||||
/// \brief Table of subdivision stencils.
|
||||
///
|
||||
/// Stencils are the most direct method of evaluation of locations on the limit
|
||||
@ -122,18 +137,20 @@ protected:
|
||||
/// recomputed simply by applying the blending weights to the series of coarse
|
||||
/// control vertices.
|
||||
///
|
||||
class StencilTable {
|
||||
StencilTable(int numControlVerts,
|
||||
template <typename REAL>
|
||||
class StencilTableReal {
|
||||
protected:
|
||||
StencilTableReal(int numControlVerts,
|
||||
std::vector<int> const& offsets,
|
||||
std::vector<int> const& sizes,
|
||||
std::vector<int> const& sources,
|
||||
std::vector<float> const& weights,
|
||||
std::vector<REAL> const& weights,
|
||||
bool includeCoarseVerts,
|
||||
size_t firstOffset);
|
||||
|
||||
public:
|
||||
|
||||
virtual ~StencilTable() {};
|
||||
virtual ~StencilTableReal() {};
|
||||
|
||||
/// \brief Returns the number of stencils in the table
|
||||
int GetNumStencils() const {
|
||||
@ -146,7 +163,7 @@ public:
|
||||
}
|
||||
|
||||
/// \brief Returns a Stencil at index i in the table
|
||||
Stencil GetStencil(Index i) const;
|
||||
StencilReal<REAL> GetStencil(Index i) const;
|
||||
|
||||
/// \brief Returns the number of control vertices of each stencil in the table
|
||||
std::vector<int> const & GetSizes() const {
|
||||
@ -164,12 +181,12 @@ public:
|
||||
}
|
||||
|
||||
/// \brief Returns the stencil interpolation weights
|
||||
std::vector<float> const & GetWeights() const {
|
||||
std::vector<REAL> const & GetWeights() const {
|
||||
return _weights;
|
||||
}
|
||||
|
||||
/// \brief Returns the stencil at index i in the table
|
||||
Stencil operator[] (Index index) const;
|
||||
StencilReal<REAL> operator[] (Index index) const;
|
||||
|
||||
/// \brief Updates point values based on the control values
|
||||
///
|
||||
@ -187,7 +204,7 @@ public:
|
||||
///
|
||||
template <class T>
|
||||
void UpdateValues(T const *controlValues, T *values, Index start=-1, Index end=-1) const {
|
||||
update(controlValues, values, _weights, start, end);
|
||||
this->update(controlValues, values, _weights, start, end);
|
||||
}
|
||||
|
||||
/// \brief Clears the stencils from the table
|
||||
@ -196,8 +213,9 @@ public:
|
||||
protected:
|
||||
|
||||
// Update values by applying cached stencil weights to new control values
|
||||
template <class T> void update( T const *controlValues, T *values,
|
||||
std::vector<float> const & valueWeights, Index start, Index end) const;
|
||||
template <class T>
|
||||
void update( T const *controlValues, T *values,
|
||||
std::vector<REAL> const & valueWeights, Index start, Index end) const;
|
||||
|
||||
// Populate the offsets table from the stencil sizes in _sizes (factory helper)
|
||||
void generateOffsets();
|
||||
@ -215,27 +233,55 @@ protected:
|
||||
void finalize();
|
||||
|
||||
protected:
|
||||
StencilTable() : _numControlVertices(0) {}
|
||||
StencilTable(int numControlVerts)
|
||||
StencilTableReal() : _numControlVertices(0) {}
|
||||
StencilTableReal(int numControlVerts)
|
||||
: _numControlVertices(numControlVerts)
|
||||
{ }
|
||||
|
||||
friend class StencilTableFactory;
|
||||
friend class PatchTableBuilder;
|
||||
friend class StencilTableFactoryReal<REAL>;
|
||||
friend class Far::PatchTableBuilder;
|
||||
|
||||
int _numControlVertices; // number of control vertices
|
||||
|
||||
std::vector<int> _sizes; // number of coefficients for each stencil
|
||||
std::vector<Index> _offsets, // offset to the start of each stencil
|
||||
_indices; // indices of contributing coarse vertices
|
||||
std::vector<float> _weights; // stencil weight coefficients
|
||||
std::vector<REAL> _weights; // stencil weight coefficients
|
||||
};
|
||||
|
||||
/// \brief Stencil table class wrapping the template for compatibility.
|
||||
///
|
||||
class StencilTable : public StencilTableReal<float> {
|
||||
protected:
|
||||
typedef StencilTableReal<float> BaseTable;
|
||||
|
||||
public:
|
||||
Stencil GetStencil(Index index) const {
|
||||
return Stencil(BaseTable::GetStencil(index));
|
||||
}
|
||||
Stencil operator[] (Index index) const {
|
||||
return Stencil(BaseTable::GetStencil(index));
|
||||
}
|
||||
|
||||
protected:
|
||||
StencilTable() : BaseTable() { }
|
||||
StencilTable(int numControlVerts) : BaseTable(numControlVerts) { }
|
||||
StencilTable(int numControlVerts,
|
||||
std::vector<int> const& offsets,
|
||||
std::vector<int> const& sizes,
|
||||
std::vector<int> const& sources,
|
||||
std::vector<float> const& weights,
|
||||
bool includeCoarseVerts,
|
||||
size_t firstOffset)
|
||||
: BaseTable(numControlVerts, offsets,
|
||||
sizes, sources, weights, includeCoarseVerts, firstOffset) { }
|
||||
};
|
||||
|
||||
|
||||
/// \brief Limit point stencil descriptor
|
||||
///
|
||||
class LimitStencil : public Stencil {
|
||||
|
||||
template <typename REAL>
|
||||
class LimitStencilReal : public StencilReal<REAL> {
|
||||
public:
|
||||
|
||||
/// \brief Constructor
|
||||
@ -256,15 +302,15 @@ public:
|
||||
///
|
||||
/// @param dvvWeights Table pointer to the 'vv' derivative weights
|
||||
///
|
||||
LimitStencil( int* size,
|
||||
Index * indices,
|
||||
float * weights,
|
||||
float * duWeights=0,
|
||||
float * dvWeights=0,
|
||||
float * duuWeights=0,
|
||||
float * duvWeights=0,
|
||||
float * dvvWeights=0)
|
||||
: Stencil(size, indices, weights),
|
||||
LimitStencilReal( int* size,
|
||||
Index * indices,
|
||||
REAL * weights,
|
||||
REAL * duWeights=0,
|
||||
REAL * dvWeights=0,
|
||||
REAL * duuWeights=0,
|
||||
REAL * duvWeights=0,
|
||||
REAL * dvvWeights=0)
|
||||
: StencilReal<REAL>(size, indices, weights),
|
||||
_duWeights(duWeights),
|
||||
_dvWeights(dvWeights),
|
||||
_duuWeights(duuWeights),
|
||||
@ -273,36 +319,36 @@ public:
|
||||
}
|
||||
|
||||
/// \brief Returns the u derivative weights
|
||||
float const * GetDuWeights() const {
|
||||
REAL const * GetDuWeights() const {
|
||||
return _duWeights;
|
||||
}
|
||||
|
||||
/// \brief Returns the v derivative weights
|
||||
float const * GetDvWeights() const {
|
||||
REAL const * GetDvWeights() const {
|
||||
return _dvWeights;
|
||||
}
|
||||
|
||||
/// \brief Returns the uu derivative weights
|
||||
float const * GetDuuWeights() const {
|
||||
REAL const * GetDuuWeights() const {
|
||||
return _duuWeights;
|
||||
}
|
||||
|
||||
/// \brief Returns the uv derivative weights
|
||||
float const * GetDuvWeights() const {
|
||||
REAL const * GetDuvWeights() const {
|
||||
return _duvWeights;
|
||||
}
|
||||
|
||||
/// \brief Returns the vv derivative weights
|
||||
float const * GetDvvWeights() const {
|
||||
REAL const * GetDvvWeights() const {
|
||||
return _dvvWeights;
|
||||
}
|
||||
|
||||
/// \brief Advance to the next stencil in the table
|
||||
void Next() {
|
||||
int stride = *_size;
|
||||
++_size;
|
||||
_indices += stride;
|
||||
_weights += stride;
|
||||
int stride = *this->_size;
|
||||
++this->_size;
|
||||
this->_indices += stride;
|
||||
this->_weights += stride;
|
||||
if (_duWeights) _duWeights += stride;
|
||||
if (_dvWeights) _dvWeights += stride;
|
||||
if (_duuWeights) _duuWeights += stride;
|
||||
@ -312,63 +358,81 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
friend class StencilTableFactory;
|
||||
friend class LimitStencilTableFactory;
|
||||
friend class StencilTableFactoryReal<REAL>;
|
||||
friend class LimitStencilTableFactoryReal<REAL>;
|
||||
|
||||
float * _duWeights, // pointer to stencil u derivative limit weights
|
||||
REAL * _duWeights, // pointer to stencil u derivative limit weights
|
||||
* _dvWeights, // pointer to stencil v derivative limit weights
|
||||
* _duuWeights, // pointer to stencil uu derivative limit weights
|
||||
* _duvWeights, // pointer to stencil uv derivative limit weights
|
||||
* _dvvWeights; // pointer to stencil vv derivative limit weights
|
||||
};
|
||||
|
||||
/// \brief Limit point stencil class wrapping the template for compatibility.
|
||||
///
|
||||
class LimitStencil : LimitStencilReal<float> {
|
||||
protected:
|
||||
typedef LimitStencilReal<float> BaseStencil;
|
||||
|
||||
public:
|
||||
LimitStencil(BaseStencil const & other) : BaseStencil(other) { }
|
||||
LimitStencil(int* size, Index * indices, float * weights,
|
||||
float * duWeights=0, float * dvWeights=0,
|
||||
float * duuWeights=0, float * duvWeights=0, float * dvvWeights=0)
|
||||
: BaseStencil(size, indices, weights,
|
||||
duWeights, dvWeights, duuWeights, duvWeights, dvvWeights) { }
|
||||
};
|
||||
|
||||
|
||||
/// \brief Table of limit subdivision stencils.
|
||||
///
|
||||
///
|
||||
class LimitStencilTable : public StencilTable {
|
||||
LimitStencilTable(int numControlVerts,
|
||||
template <typename REAL>
|
||||
class LimitStencilTableReal : public StencilTableReal<REAL> {
|
||||
protected:
|
||||
LimitStencilTableReal(
|
||||
int numControlVerts,
|
||||
std::vector<int> const& offsets,
|
||||
std::vector<int> const& sizes,
|
||||
std::vector<int> const& sources,
|
||||
std::vector<float> const& weights,
|
||||
std::vector<float> const& duWeights,
|
||||
std::vector<float> const& dvWeights,
|
||||
std::vector<float> const& duuWeights,
|
||||
std::vector<float> const& duvWeights,
|
||||
std::vector<float> const& dvvWeights,
|
||||
std::vector<REAL> const& weights,
|
||||
std::vector<REAL> const& duWeights,
|
||||
std::vector<REAL> const& dvWeights,
|
||||
std::vector<REAL> const& duuWeights,
|
||||
std::vector<REAL> const& duvWeights,
|
||||
std::vector<REAL> const& dvvWeights,
|
||||
bool includeCoarseVerts,
|
||||
size_t firstOffset);
|
||||
|
||||
public:
|
||||
|
||||
/// \brief Returns a LimitStencil at index i in the table
|
||||
LimitStencil GetLimitStencil(Index i) const;
|
||||
LimitStencilReal<REAL> GetLimitStencil(Index i) const;
|
||||
|
||||
/// \brief Returns the limit stencil at index i in the table
|
||||
LimitStencil operator[] (Index index) const;
|
||||
LimitStencilReal<REAL> operator[] (Index index) const;
|
||||
|
||||
/// \brief Returns the 'u' derivative stencil interpolation weights
|
||||
std::vector<float> const & GetDuWeights() const {
|
||||
std::vector<REAL> const & GetDuWeights() const {
|
||||
return _duWeights;
|
||||
}
|
||||
|
||||
/// \brief Returns the 'v' derivative stencil interpolation weights
|
||||
std::vector<float> const & GetDvWeights() const {
|
||||
std::vector<REAL> const & GetDvWeights() const {
|
||||
return _dvWeights;
|
||||
}
|
||||
|
||||
/// \brief Returns the 'uu' derivative stencil interpolation weights
|
||||
std::vector<float> const & GetDuuWeights() const {
|
||||
std::vector<REAL> const & GetDuuWeights() const {
|
||||
return _duuWeights;
|
||||
}
|
||||
|
||||
/// \brief Returns the 'uv' derivative stencil interpolation weights
|
||||
std::vector<float> const & GetDuvWeights() const {
|
||||
std::vector<REAL> const & GetDuvWeights() const {
|
||||
return _duvWeights;
|
||||
}
|
||||
|
||||
/// \brief Returns the 'vv' derivative stencil interpolation weights
|
||||
std::vector<float> const & GetDvvWeights() const {
|
||||
std::vector<REAL> const & GetDvvWeights() const {
|
||||
return _dvvWeights;
|
||||
}
|
||||
|
||||
@ -393,8 +457,8 @@ public:
|
||||
void UpdateDerivs(T const *controlValues, T *uderivs, T *vderivs,
|
||||
int start=-1, int end=-1) const {
|
||||
|
||||
update(controlValues, uderivs, _duWeights, start, end);
|
||||
update(controlValues, vderivs, _dvWeights, start, end);
|
||||
this->update(controlValues, uderivs, _duWeights, start, end);
|
||||
this->update(controlValues, vderivs, _dvWeights, start, end);
|
||||
}
|
||||
|
||||
/// \brief Updates 2nd derivative values based on the control values
|
||||
@ -421,37 +485,71 @@ public:
|
||||
void Update2ndDerivs(T const *controlValues, T *uuderivs, T *uvderivs, T *vvderivs,
|
||||
int start=-1, int end=-1) const {
|
||||
|
||||
update(controlValues, uuderivs, _duuWeights, start, end);
|
||||
update(controlValues, uvderivs, _duvWeights, start, end);
|
||||
update(controlValues, vvderivs, _dvvWeights, start, end);
|
||||
this->update(controlValues, uuderivs, _duuWeights, start, end);
|
||||
this->update(controlValues, uvderivs, _duvWeights, start, end);
|
||||
this->update(controlValues, vvderivs, _dvvWeights, start, end);
|
||||
}
|
||||
|
||||
/// \brief Clears the stencils from the table
|
||||
void Clear();
|
||||
|
||||
private:
|
||||
friend class LimitStencilTableFactory;
|
||||
friend class LimitStencilTableFactoryReal<REAL>;
|
||||
|
||||
// Resize the table arrays (factory helper)
|
||||
void resize(int nstencils, int nelems);
|
||||
|
||||
private:
|
||||
std::vector<float> _duWeights, // u derivative limit stencil weights
|
||||
std::vector<REAL> _duWeights, // u derivative limit stencil weights
|
||||
_dvWeights, // v derivative limit stencil weights
|
||||
_duuWeights, // uu derivative limit stencil weights
|
||||
_duvWeights, // uv derivative limit stencil weights
|
||||
_dvvWeights; // vv derivative limit stencil weights
|
||||
};
|
||||
|
||||
/// \brief Limit stencil table class wrapping the template for compatibility.
|
||||
///
|
||||
class LimitStencilTable : public LimitStencilTableReal<float> {
|
||||
protected:
|
||||
typedef LimitStencilTableReal<float> BaseTable;
|
||||
|
||||
public:
|
||||
LimitStencil GetLimitStencil(Index index) const {
|
||||
return LimitStencil(BaseTable::GetLimitStencil(index));
|
||||
}
|
||||
LimitStencil operator[] (Index index) const {
|
||||
return LimitStencil(BaseTable::GetLimitStencil(index));
|
||||
}
|
||||
|
||||
protected:
|
||||
LimitStencilTable(int numControlVerts,
|
||||
std::vector<int> const& offsets,
|
||||
std::vector<int> const& sizes,
|
||||
std::vector<int> const& sources,
|
||||
std::vector<float> const& weights,
|
||||
std::vector<float> const& duWeights,
|
||||
std::vector<float> const& dvWeights,
|
||||
std::vector<float> const& duuWeights,
|
||||
std::vector<float> const& duvWeights,
|
||||
std::vector<float> const& dvvWeights,
|
||||
bool includeCoarseVerts,
|
||||
size_t firstOffset)
|
||||
: BaseTable(numControlVerts,
|
||||
offsets, sizes, sources, weights,
|
||||
duWeights, dvWeights, duuWeights, duvWeights, dvvWeights,
|
||||
includeCoarseVerts, firstOffset) { }
|
||||
};
|
||||
|
||||
|
||||
// Update values by applying cached stencil weights to new control values
|
||||
template <typename REAL>
|
||||
template <class T> void
|
||||
StencilTable::update(T const *controlValues, T *values,
|
||||
std::vector<float> const &valueWeights, Index start, Index end) const {
|
||||
StencilTableReal<REAL>::update(T const *controlValues, T *values,
|
||||
std::vector<REAL> const &valueWeights, Index start, Index end) const {
|
||||
|
||||
int const * sizes = &_sizes.at(0);
|
||||
Index const * indices = &_indices.at(0);
|
||||
float const * weights = &valueWeights.at(0);
|
||||
REAL const * weights = &valueWeights.at(0);
|
||||
|
||||
if (start>0) {
|
||||
assert(start<(Index)_offsets.size());
|
||||
@ -478,8 +576,9 @@ StencilTable::update(T const *controlValues, T *values,
|
||||
}
|
||||
}
|
||||
|
||||
template <typename REAL>
|
||||
inline void
|
||||
StencilTable::generateOffsets() {
|
||||
StencilTableReal<REAL>::generateOffsets() {
|
||||
Index offset=0;
|
||||
int noffsets = (int)_sizes.size();
|
||||
_offsets.resize(noffsets);
|
||||
@ -489,93 +588,104 @@ StencilTable::generateOffsets() {
|
||||
}
|
||||
}
|
||||
|
||||
template <typename REAL>
|
||||
inline void
|
||||
StencilTable::resize(int nstencils, int nelems) {
|
||||
StencilTableReal<REAL>::resize(int nstencils, int nelems) {
|
||||
_sizes.resize(nstencils);
|
||||
_indices.resize(nelems);
|
||||
_weights.resize(nelems);
|
||||
}
|
||||
|
||||
template <typename REAL>
|
||||
inline void
|
||||
StencilTable::reserve(int nstencils, int nelems) {
|
||||
StencilTableReal<REAL>::reserve(int nstencils, int nelems) {
|
||||
_sizes.reserve(nstencils);
|
||||
_indices.reserve(nelems);
|
||||
_weights.reserve(nelems);
|
||||
}
|
||||
|
||||
template <typename REAL>
|
||||
inline void
|
||||
StencilTable::shrinkToFit() {
|
||||
StencilTableReal<REAL>::shrinkToFit() {
|
||||
std::vector<int>(_sizes).swap(_sizes);
|
||||
std::vector<Index>(_indices).swap(_indices);
|
||||
std::vector<float>(_weights).swap(_weights);
|
||||
std::vector<REAL>(_weights).swap(_weights);
|
||||
}
|
||||
|
||||
template <typename REAL>
|
||||
inline void
|
||||
StencilTable::finalize() {
|
||||
StencilTableReal<REAL>::finalize() {
|
||||
shrinkToFit();
|
||||
generateOffsets();
|
||||
}
|
||||
|
||||
// Returns a Stencil at index i in the table
|
||||
inline Stencil
|
||||
StencilTable::GetStencil(Index i) const {
|
||||
template <typename REAL>
|
||||
inline StencilReal<REAL>
|
||||
StencilTableReal<REAL>::GetStencil(Index i) const {
|
||||
assert((! _offsets.empty()) && i<(int)_offsets.size());
|
||||
|
||||
Index ofs = _offsets[i];
|
||||
|
||||
return Stencil( const_cast<int*>(&_sizes[i]),
|
||||
const_cast<Index *>(&_indices[ofs]),
|
||||
const_cast<float *>(&_weights[ofs]) );
|
||||
return StencilReal<REAL>(const_cast<int*>(&_sizes[i]),
|
||||
const_cast<Index*>(&_indices[ofs]),
|
||||
const_cast<REAL*>(&_weights[ofs]));
|
||||
}
|
||||
|
||||
inline Stencil
|
||||
StencilTable::operator[] (Index index) const {
|
||||
template <typename REAL>
|
||||
inline StencilReal<REAL>
|
||||
StencilTableReal<REAL>::operator[] (Index index) const {
|
||||
return GetStencil(index);
|
||||
}
|
||||
|
||||
template <typename REAL>
|
||||
inline void
|
||||
LimitStencilTable::resize(int nstencils, int nelems) {
|
||||
StencilTable::resize(nstencils, nelems);
|
||||
LimitStencilTableReal<REAL>::resize(int nstencils, int nelems) {
|
||||
StencilTableReal<REAL>::resize(nstencils, nelems);
|
||||
_duWeights.resize(nelems);
|
||||
_dvWeights.resize(nelems);
|
||||
}
|
||||
|
||||
// Returns a LimitStencil at index i in the table
|
||||
inline LimitStencil
|
||||
LimitStencilTable::GetLimitStencil(Index i) const {
|
||||
assert((! GetOffsets().empty()) && i<(int)GetOffsets().size());
|
||||
template <typename REAL>
|
||||
inline LimitStencilReal<REAL>
|
||||
LimitStencilTableReal<REAL>::GetLimitStencil(Index i) const {
|
||||
assert((! this->GetOffsets().empty()) && i<(int)this->GetOffsets().size());
|
||||
|
||||
Index ofs = GetOffsets()[i];
|
||||
Index ofs = this->GetOffsets()[i];
|
||||
|
||||
if (!_duWeights.empty() && !_dvWeights.empty() &&
|
||||
!_duuWeights.empty() && !_duvWeights.empty() && !_dvvWeights.empty()) {
|
||||
return LimitStencil( const_cast<int *>(&GetSizes()[i]),
|
||||
const_cast<Index *>(&GetControlIndices()[ofs]),
|
||||
const_cast<float *>(&GetWeights()[ofs]),
|
||||
const_cast<float *>(&GetDuWeights()[ofs]),
|
||||
const_cast<float *>(&GetDvWeights()[ofs]),
|
||||
const_cast<float *>(&GetDuuWeights()[ofs]),
|
||||
const_cast<float *>(&GetDuvWeights()[ofs]),
|
||||
const_cast<float *>(&GetDvvWeights()[ofs]) );
|
||||
return LimitStencilReal<REAL>(
|
||||
const_cast<int *>(&this->GetSizes()[i]),
|
||||
const_cast<Index *>(&this->GetControlIndices()[ofs]),
|
||||
const_cast<REAL *>(&this->GetWeights()[ofs]),
|
||||
const_cast<REAL *>(&GetDuWeights()[ofs]),
|
||||
const_cast<REAL *>(&GetDvWeights()[ofs]),
|
||||
const_cast<REAL *>(&GetDuuWeights()[ofs]),
|
||||
const_cast<REAL *>(&GetDuvWeights()[ofs]),
|
||||
const_cast<REAL *>(&GetDvvWeights()[ofs]) );
|
||||
} else if (!_duWeights.empty() && !_dvWeights.empty()) {
|
||||
return LimitStencil( const_cast<int *>(&GetSizes()[i]),
|
||||
const_cast<Index *>(&GetControlIndices()[ofs]),
|
||||
const_cast<float *>(&GetWeights()[ofs]),
|
||||
const_cast<float *>(&GetDuWeights()[ofs]),
|
||||
const_cast<float *>(&GetDvWeights()[ofs]) );
|
||||
return LimitStencilReal<REAL>(
|
||||
const_cast<int *>(&this->GetSizes()[i]),
|
||||
const_cast<Index *>(&this->GetControlIndices()[ofs]),
|
||||
const_cast<REAL *>(&this->GetWeights()[ofs]),
|
||||
const_cast<REAL *>(&GetDuWeights()[ofs]),
|
||||
const_cast<REAL *>(&GetDvWeights()[ofs]) );
|
||||
} else {
|
||||
return LimitStencil( const_cast<int *>(&GetSizes()[i]),
|
||||
const_cast<Index *>(&GetControlIndices()[ofs]),
|
||||
const_cast<float *>(&GetWeights()[ofs]) );
|
||||
return LimitStencilReal<REAL>(
|
||||
const_cast<int *>(&this->GetSizes()[i]),
|
||||
const_cast<Index *>(&this->GetControlIndices()[ofs]),
|
||||
const_cast<REAL *>(&this->GetWeights()[ofs]) );
|
||||
}
|
||||
}
|
||||
|
||||
inline LimitStencil
|
||||
LimitStencilTable::operator[] (Index index) const {
|
||||
template <typename REAL>
|
||||
inline LimitStencilReal<REAL>
|
||||
LimitStencilTableReal<REAL>::operator[] (Index index) const {
|
||||
return GetLimitStencil(index);
|
||||
}
|
||||
|
||||
|
||||
} // end namespace Far
|
||||
|
||||
} // end namespace OPENSUBDIV_VERSION
|
||||
|
@ -39,13 +39,16 @@ namespace OPENSUBDIV_VERSION {
|
||||
|
||||
namespace Far {
|
||||
|
||||
using internal::StencilBuilder;
|
||||
|
||||
namespace {
|
||||
#ifdef __INTEL_COMPILER
|
||||
#pragma warning (push)
|
||||
#pragma warning disable 1572
|
||||
#endif
|
||||
|
||||
inline bool isWeightZero(float w) { return (w == 0.0f); }
|
||||
template <typename REAL>
|
||||
inline bool isWeightZero(REAL w) { return (w == (REAL) 0.0); }
|
||||
|
||||
#ifdef __INTEL_COMPILER
|
||||
#pragma warning (pop)
|
||||
@ -54,15 +57,17 @@ namespace {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template <typename REAL>
|
||||
void
|
||||
StencilTableFactory::generateControlVertStencils(
|
||||
int numControlVerts, Stencil & dst) {
|
||||
StencilTableFactoryReal<REAL>::generateControlVertStencils(
|
||||
int numControlVerts,
|
||||
StencilReal<REAL> & dst) {
|
||||
|
||||
// Control vertices contribute a single index with a weight of 1.0
|
||||
for (int i=0; i<numControlVerts; ++i) {
|
||||
*dst._size = 1;
|
||||
*dst._indices = i;
|
||||
*dst._weights = 1.0f;
|
||||
*dst._weights = (REAL) 1.0;
|
||||
dst.Next();
|
||||
}
|
||||
}
|
||||
@ -70,8 +75,9 @@ StencilTableFactory::generateControlVertStencils(
|
||||
//
|
||||
// StencilTable factory
|
||||
//
|
||||
StencilTable const *
|
||||
StencilTableFactory::Create(TopologyRefiner const & refiner,
|
||||
template <typename REAL>
|
||||
StencilTableReal<REAL> const *
|
||||
StencilTableFactoryReal<REAL>::Create(TopologyRefiner const & refiner,
|
||||
Options options) {
|
||||
|
||||
bool interpolateVertex = options.interpolationMode==INTERPOLATE_VERTEX;
|
||||
@ -84,12 +90,12 @@ StencilTableFactory::Create(TopologyRefiner const & refiner,
|
||||
|
||||
int maxlevel = std::min(int(options.maxLevel), refiner.GetMaxLevel());
|
||||
if (maxlevel==0 && (! options.generateControlVerts)) {
|
||||
StencilTable * result = new StencilTable;
|
||||
StencilTableReal<REAL> * result = new StencilTableReal<REAL>;
|
||||
result->_numControlVertices = numControlVertices;
|
||||
return result;
|
||||
}
|
||||
|
||||
internal::StencilBuilder builder(numControlVertices,
|
||||
StencilBuilder<REAL> builder(numControlVertices,
|
||||
/*genControlVerts*/ true,
|
||||
/*compactWeights*/ true);
|
||||
|
||||
@ -99,8 +105,8 @@ StencilTableFactory::Create(TopologyRefiner const & refiner,
|
||||
//
|
||||
PrimvarRefiner primvarRefiner(refiner);
|
||||
|
||||
internal::StencilBuilder::Index srcIndex(&builder, 0);
|
||||
internal::StencilBuilder::Index dstIndex(&builder, numControlVertices);
|
||||
typename StencilBuilder<REAL>::Index srcIndex(&builder, 0);
|
||||
typename StencilBuilder<REAL>::Index dstIndex(&builder, numControlVertices);
|
||||
|
||||
for (int level=1; level<=maxlevel; ++level) {
|
||||
if (interpolateVertex) {
|
||||
@ -134,8 +140,8 @@ StencilTableFactory::Create(TopologyRefiner const & refiner,
|
||||
|
||||
// Copy stencils from the StencilBuilder into the StencilTable.
|
||||
// Always initialize numControlVertices (useful for torus case)
|
||||
StencilTable * result =
|
||||
new StencilTable(numControlVertices,
|
||||
StencilTableReal<REAL> * result =
|
||||
new StencilTableReal<REAL>(numControlVertices,
|
||||
builder.GetStencilOffsets(),
|
||||
builder.GetStencilSizes(),
|
||||
builder.GetStencilSources(),
|
||||
@ -147,8 +153,10 @@ StencilTableFactory::Create(TopologyRefiner const & refiner,
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
StencilTable const *
|
||||
StencilTableFactory::Create(int numTables, StencilTable const ** tables) {
|
||||
template <typename REAL>
|
||||
StencilTableReal<REAL> const *
|
||||
StencilTableFactoryReal<REAL>::Create(int numTables,
|
||||
StencilTableReal<REAL> const ** tables) {
|
||||
|
||||
// XXXtakahito:
|
||||
// This function returns NULL for empty inputs or erroneous condition.
|
||||
@ -166,7 +174,7 @@ StencilTableFactory::Create(int numTables, StencilTable const ** tables) {
|
||||
|
||||
for (int i=0; i<numTables; ++i) {
|
||||
|
||||
StencilTable const * st = tables[i];
|
||||
StencilTableReal<REAL> const * st = tables[i];
|
||||
// allow the tables could have a null entry.
|
||||
if (!st) continue;
|
||||
|
||||
@ -182,21 +190,21 @@ StencilTableFactory::Create(int numTables, StencilTable const ** tables) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
StencilTable * result = new StencilTable;
|
||||
StencilTableReal<REAL> * result = new StencilTableReal<REAL>;
|
||||
result->resize(nstencils, nelems);
|
||||
|
||||
int * sizes = &result->_sizes[0];
|
||||
Index * indices = &result->_indices[0];
|
||||
float * weights = &result->_weights[0];
|
||||
REAL * weights = &result->_weights[0];
|
||||
for (int i=0; i<numTables; ++i) {
|
||||
StencilTable const * st = tables[i];
|
||||
StencilTableReal<REAL> const * st = tables[i];
|
||||
if (!st) continue;
|
||||
|
||||
int st_nstencils = st->GetNumStencils(),
|
||||
st_nelems = (int)st->_indices.size();
|
||||
memcpy(sizes, &st->_sizes[0], st_nstencils*sizeof(int));
|
||||
memcpy(indices, &st->_indices[0], st_nelems*sizeof(Index));
|
||||
memcpy(weights, &st->_weights[0], st_nelems*sizeof(float));
|
||||
memcpy(weights, &st->_weights[0], st_nelems*sizeof(REAL));
|
||||
|
||||
sizes += st_nstencils;
|
||||
indices += st_nelems;
|
||||
@ -213,11 +221,12 @@ StencilTableFactory::Create(int numTables, StencilTable const ** tables) {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
StencilTable const *
|
||||
StencilTableFactory::AppendLocalPointStencilTable(
|
||||
template <typename REAL>
|
||||
StencilTableReal<REAL> const *
|
||||
StencilTableFactoryReal<REAL>::AppendLocalPointStencilTable(
|
||||
TopologyRefiner const &refiner,
|
||||
StencilTable const * baseStencilTable,
|
||||
StencilTable const * localPointStencilTable,
|
||||
StencilTableReal<REAL> const * baseStencilTable,
|
||||
StencilTableReal<REAL> const * localPointStencilTable,
|
||||
bool factorize) {
|
||||
|
||||
return appendLocalPointStencilTable(
|
||||
@ -228,11 +237,12 @@ StencilTableFactory::AppendLocalPointStencilTable(
|
||||
factorize);
|
||||
}
|
||||
|
||||
StencilTable const *
|
||||
StencilTableFactory::AppendLocalPointStencilTableFaceVarying(
|
||||
template <typename REAL>
|
||||
StencilTableReal<REAL> const *
|
||||
StencilTableFactoryReal<REAL>::AppendLocalPointStencilTableFaceVarying(
|
||||
TopologyRefiner const &refiner,
|
||||
StencilTable const * baseStencilTable,
|
||||
StencilTable const * localPointStencilTable,
|
||||
StencilTableReal<REAL> const * baseStencilTable,
|
||||
StencilTableReal<REAL> const * localPointStencilTable,
|
||||
int channel,
|
||||
bool factorize) {
|
||||
|
||||
@ -244,11 +254,12 @@ StencilTableFactory::AppendLocalPointStencilTableFaceVarying(
|
||||
factorize);
|
||||
}
|
||||
|
||||
StencilTable const *
|
||||
StencilTableFactory::appendLocalPointStencilTable(
|
||||
template <typename REAL>
|
||||
StencilTableReal<REAL> const *
|
||||
StencilTableFactoryReal<REAL>::appendLocalPointStencilTable(
|
||||
TopologyRefiner const &refiner,
|
||||
StencilTable const * baseStencilTable,
|
||||
StencilTable const * localPointStencilTable,
|
||||
StencilTableReal<REAL> const * baseStencilTable,
|
||||
StencilTableReal<REAL> const * localPointStencilTable,
|
||||
int channel,
|
||||
bool factorize) {
|
||||
|
||||
@ -317,20 +328,20 @@ StencilTableFactory::appendLocalPointStencilTable(
|
||||
int nLocalPointStencils = localPointStencilTable->GetNumStencils();
|
||||
int nLocalPointStencilsElements = 0;
|
||||
|
||||
internal::StencilBuilder builder(nControlVerts,
|
||||
StencilBuilder<REAL> builder(nControlVerts,
|
||||
/*genControlVerts*/ false,
|
||||
/*compactWeights*/ factorize);
|
||||
internal::StencilBuilder::Index origin(&builder, 0);
|
||||
internal::StencilBuilder::Index dst = origin;
|
||||
internal::StencilBuilder::Index srcIdx = origin;
|
||||
typename StencilBuilder<REAL>::Index origin(&builder, 0);
|
||||
typename StencilBuilder<REAL>::Index dst = origin;
|
||||
typename StencilBuilder<REAL>::Index srcIdx = origin;
|
||||
|
||||
for (int i = 0 ; i < nLocalPointStencils; ++i) {
|
||||
Stencil src = localPointStencilTable->GetStencil(i);
|
||||
StencilReal<REAL> src = localPointStencilTable->GetStencil(i);
|
||||
dst = origin[i];
|
||||
for (int j = 0; j < src.GetSize(); ++j) {
|
||||
Index index = src.GetVertexIndices()[j];
|
||||
float weight = src.GetWeights()[j];
|
||||
if (isWeightZero(weight)) continue;
|
||||
REAL weight = src.GetWeights()[j];
|
||||
if (isWeightZero<REAL>(weight)) continue;
|
||||
|
||||
if (factorize) {
|
||||
dst.AddWithWeight(
|
||||
@ -349,14 +360,14 @@ StencilTableFactory::appendLocalPointStencilTable(
|
||||
}
|
||||
|
||||
// create new stencil table
|
||||
StencilTable * result = new StencilTable;
|
||||
StencilTableReal<REAL> * result = new StencilTableReal<REAL>;
|
||||
result->_numControlVertices = nControlVerts;
|
||||
result->resize(nBaseStencils + nLocalPointStencils,
|
||||
nBaseStencilsElements + nLocalPointStencilsElements);
|
||||
|
||||
int* sizes = &result->_sizes[0];
|
||||
Index * indices = &result->_indices[0];
|
||||
float * weights = &result->_weights[0];
|
||||
REAL * weights = &result->_weights[0];
|
||||
|
||||
// put base stencils first
|
||||
memcpy(sizes, &baseStencilTable->_sizes[0],
|
||||
@ -364,7 +375,7 @@ StencilTableFactory::appendLocalPointStencilTable(
|
||||
memcpy(indices, &baseStencilTable->_indices[0],
|
||||
nBaseStencilsElements*sizeof(Index));
|
||||
memcpy(weights, &baseStencilTable->_weights[0],
|
||||
nBaseStencilsElements*sizeof(float));
|
||||
nBaseStencilsElements*sizeof(REAL));
|
||||
|
||||
sizes += nBaseStencils;
|
||||
indices += nBaseStencilsElements;
|
||||
@ -388,12 +399,13 @@ StencilTableFactory::appendLocalPointStencilTable(
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
LimitStencilTable const *
|
||||
LimitStencilTableFactory::Create(TopologyRefiner const & refiner,
|
||||
template <typename REAL>
|
||||
LimitStencilTableReal<REAL> const *
|
||||
LimitStencilTableFactoryReal<REAL>::Create(TopologyRefiner const & refiner,
|
||||
LocationArrayVec const & locationArrays,
|
||||
StencilTable const * cvStencilsIn,
|
||||
PatchTable const * patchTableIn,
|
||||
Options options) {
|
||||
StencilTableReal<REAL> const * cvStencilsIn,
|
||||
PatchTable const * patchTableIn,
|
||||
Options options) {
|
||||
|
||||
// Compute the total number of stencils to generate
|
||||
int numStencils=0, numLimitStencils=0;
|
||||
@ -409,14 +421,14 @@ LimitStencilTableFactory::Create(TopologyRefiner const & refiner,
|
||||
|
||||
int maxlevel = refiner.GetMaxLevel();
|
||||
|
||||
StencilTable const * cvstencils = cvStencilsIn;
|
||||
StencilTableReal<REAL> const * cvstencils = cvStencilsIn;
|
||||
if (! cvstencils) {
|
||||
// Generate stencils for the control vertices - this is necessary to
|
||||
// properly factorize patches with control vertices at level 0 (natural
|
||||
// regular patches, such as in a torus)
|
||||
// note: the control vertices of the mesh are added as single-index
|
||||
// stencils of weight 1.0f
|
||||
StencilTableFactory::Options stencilTableOptions;
|
||||
typename StencilTableFactoryReal<REAL>::Options stencilTableOptions;
|
||||
stencilTableOptions.generateIntermediateLevels = uniform ? false :true;
|
||||
stencilTableOptions.generateControlVerts = true;
|
||||
stencilTableOptions.generateOffsets = true;
|
||||
@ -424,7 +436,7 @@ LimitStencilTableFactory::Create(TopologyRefiner const & refiner,
|
||||
// PERFORMANCE: We could potentially save some mem-copies by not
|
||||
// instantiating the stencil tables and work directly off the source
|
||||
// data.
|
||||
cvstencils = StencilTableFactory::Create(refiner, stencilTableOptions);
|
||||
cvstencils = StencilTableFactoryReal<REAL>::Create(refiner, stencilTableOptions);
|
||||
} else {
|
||||
// Sanity checks
|
||||
//
|
||||
@ -447,6 +459,7 @@ LimitStencilTableFactory::Create(TopologyRefiner const & refiner,
|
||||
// patch table.
|
||||
|
||||
PatchTableFactory::Options patchTableOptions;
|
||||
patchTableOptions.SetPatchPrecision<REAL>();
|
||||
patchTableOptions.SetEndCapType(
|
||||
Far::PatchTableFactory::Options::ENDCAP_GREGORY_BASIS);
|
||||
patchTableOptions.useInfSharpPatch = !uniform &&
|
||||
@ -456,10 +469,10 @@ LimitStencilTableFactory::Create(TopologyRefiner const & refiner,
|
||||
|
||||
if (! cvStencilsIn) {
|
||||
// if cvstencils is just created above, append endcap stencils
|
||||
if (StencilTable const *localPointStencilTable =
|
||||
patchtable->GetLocalPointStencilTable()) {
|
||||
StencilTable const *table =
|
||||
StencilTableFactory::AppendLocalPointStencilTable(
|
||||
if (StencilTableReal<REAL> const *localPointStencilTable =
|
||||
patchtable->GetLocalPointStencilTable<REAL>()) {
|
||||
StencilTableReal<REAL> const *table =
|
||||
StencilTableFactoryReal<REAL>::AppendLocalPointStencilTable(
|
||||
refiner, cvstencils, localPointStencilTable);
|
||||
delete cvstencils;
|
||||
cvstencils = table;
|
||||
@ -484,21 +497,20 @@ LimitStencilTableFactory::Create(TopologyRefiner const & refiner,
|
||||
//
|
||||
// Generate limit stencils for locations
|
||||
//
|
||||
|
||||
internal::StencilBuilder builder(refiner.GetLevel(0).GetNumVertices(),
|
||||
StencilBuilder<REAL> builder(refiner.GetLevel(0).GetNumVertices(),
|
||||
/*genControlVerts*/ false,
|
||||
/*compactWeights*/ true);
|
||||
internal::StencilBuilder::Index origin(&builder, 0);
|
||||
internal::StencilBuilder::Index dst = origin;
|
||||
typename StencilBuilder<REAL>::Index origin(&builder, 0);
|
||||
typename StencilBuilder<REAL>::Index dst = origin;
|
||||
|
||||
float wP[20], wDs[20], wDt[20], wDss[20], wDst[20], wDtt[20];
|
||||
REAL wP[20], wDs[20], wDt[20], wDss[20], wDst[20], wDtt[20];
|
||||
|
||||
for (size_t i=0; i<locationArrays.size(); ++i) {
|
||||
LocationArray const & array = locationArrays[i];
|
||||
assert(array.ptexIdx>=0);
|
||||
|
||||
for (int j=0; j<array.numLocations; ++j) { // for each face we're working on
|
||||
float s = array.s[j],
|
||||
REAL s = array.s[j],
|
||||
t = array.t[j]; // for each target (s,t) point on that face
|
||||
|
||||
PatchMap::Handle const * handle =
|
||||
@ -506,7 +518,7 @@ LimitStencilTableFactory::Create(TopologyRefiner const & refiner,
|
||||
if (handle) {
|
||||
ConstIndexArray cvs = patchtable->GetPatchVertices(*handle);
|
||||
|
||||
StencilTable const & src = *cvstencils;
|
||||
StencilTableReal<REAL> const & src = *cvstencils;
|
||||
dst = origin[numLimitStencils];
|
||||
|
||||
if (options.generate2ndDerivatives) {
|
||||
@ -548,7 +560,7 @@ LimitStencilTableFactory::Create(TopologyRefiner const & refiner,
|
||||
//
|
||||
// Copy the proto-stencils into the limit stencil table
|
||||
//
|
||||
LimitStencilTable * result = new LimitStencilTable(
|
||||
LimitStencilTableReal<REAL> * result = new LimitStencilTableReal<REAL>(
|
||||
refiner.GetLevel(0).GetNumVertices(),
|
||||
builder.GetStencilOffsets(),
|
||||
builder.GetStencilSizes(),
|
||||
@ -564,6 +576,16 @@ LimitStencilTableFactory::Create(TopologyRefiner const & refiner,
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Explicit instantiation for float and double:
|
||||
//
|
||||
template class StencilTableFactoryReal<float>;
|
||||
template class StencilTableFactoryReal<double>;
|
||||
|
||||
template class LimitStencilTableFactoryReal<float>;
|
||||
template class LimitStencilTableFactoryReal<double>;
|
||||
|
||||
|
||||
} // end namespace Far
|
||||
|
||||
} // end namespace OPENSUBDIV_VERSION
|
||||
|
@ -38,14 +38,17 @@ namespace Far {
|
||||
|
||||
class TopologyRefiner;
|
||||
|
||||
class Stencil;
|
||||
class StencilTable;
|
||||
class LimitStencil;
|
||||
class LimitStencilTable;
|
||||
template <typename REAL> class StencilReal;
|
||||
template <typename REAL> class StencilTableReal;
|
||||
|
||||
template <typename REAL> class LimitStencilReal;
|
||||
template <typename REAL> class LimitStencilTableReal;
|
||||
|
||||
|
||||
/// \brief A specialized factory for StencilTable
|
||||
///
|
||||
class StencilTableFactory {
|
||||
template <typename REAL>
|
||||
class StencilTableFactoryReal {
|
||||
|
||||
public:
|
||||
|
||||
@ -88,8 +91,8 @@ public:
|
||||
///
|
||||
/// @param options Options controlling the creation of the table
|
||||
///
|
||||
static StencilTable const * Create(TopologyRefiner const & refiner,
|
||||
Options options = Options());
|
||||
static StencilTableReal<REAL> const * Create(
|
||||
TopologyRefiner const & refiner, Options options = Options());
|
||||
|
||||
|
||||
/// \brief Instantiates StencilTable by concatenating an array of existing
|
||||
@ -104,7 +107,8 @@ public:
|
||||
///
|
||||
/// @param tables Array of input StencilTables
|
||||
///
|
||||
static StencilTable const * Create(int numTables, StencilTable const ** tables);
|
||||
static StencilTableReal<REAL> const * Create(
|
||||
int numTables, StencilTableReal<REAL> const ** tables);
|
||||
|
||||
|
||||
/// \brief Utility function for stencil splicing for local point stencils.
|
||||
@ -121,11 +125,11 @@ public:
|
||||
/// table so that the endcap points can be computed
|
||||
/// directly from control vertices.
|
||||
///
|
||||
static StencilTable const * AppendLocalPointStencilTable(
|
||||
TopologyRefiner const &refiner,
|
||||
StencilTable const *baseStencilTable,
|
||||
StencilTable const *localPointStencilTable,
|
||||
bool factorize = true);
|
||||
static StencilTableReal<REAL> const * AppendLocalPointStencilTable(
|
||||
TopologyRefiner const &refiner,
|
||||
StencilTableReal<REAL> const *baseStencilTable,
|
||||
StencilTableReal<REAL> const *localPointStencilTable,
|
||||
bool factorize = true);
|
||||
|
||||
/// \brief Utility function for stencil splicing for local point
|
||||
/// face-varying stencils.
|
||||
@ -144,25 +148,27 @@ public:
|
||||
/// table so that the endcap points can be computed
|
||||
/// directly from control vertices.
|
||||
///
|
||||
static StencilTable const * AppendLocalPointStencilTableFaceVarying(
|
||||
TopologyRefiner const &refiner,
|
||||
StencilTable const *baseStencilTable,
|
||||
StencilTable const *localPointStencilTable,
|
||||
int channel = 0,
|
||||
bool factorize = true);
|
||||
static StencilTableReal<REAL> const * AppendLocalPointStencilTableFaceVarying(
|
||||
TopologyRefiner const &refiner,
|
||||
StencilTableReal<REAL> const *baseStencilTable,
|
||||
StencilTableReal<REAL> const *localPointStencilTable,
|
||||
int channel = 0,
|
||||
bool factorize = true);
|
||||
|
||||
private:
|
||||
|
||||
// Generate stencils for the coarse control-vertices (single weight = 1.0f)
|
||||
static void generateControlVertStencils(int numControlVerts, Stencil & dst);
|
||||
static void generateControlVertStencils(
|
||||
int numControlVerts,
|
||||
StencilReal<REAL> & dst);
|
||||
|
||||
// Internal method to splice local point stencils
|
||||
static StencilTable const * appendLocalPointStencilTable(
|
||||
TopologyRefiner const &refiner,
|
||||
StencilTable const * baseStencilTable,
|
||||
StencilTable const * localPointStencilTable,
|
||||
int channel,
|
||||
bool factorize);
|
||||
static StencilTableReal<REAL> const * appendLocalPointStencilTable(
|
||||
TopologyRefiner const &refiner,
|
||||
StencilTableReal<REAL> const * baseStencilTable,
|
||||
StencilTableReal<REAL> const * localPointStencilTable,
|
||||
int channel,
|
||||
bool factorize);
|
||||
};
|
||||
|
||||
/// \brief A specialized factory for LimitStencilTable
|
||||
@ -176,7 +182,8 @@ private:
|
||||
/// normalized (s,t) patch coordinates. The factory exposes the LocationArray
|
||||
/// struct as a container for these location descriptors.
|
||||
///
|
||||
class LimitStencilTableFactory {
|
||||
template <typename REAL>
|
||||
class LimitStencilTableFactoryReal {
|
||||
|
||||
public:
|
||||
|
||||
@ -188,7 +195,7 @@ public:
|
||||
int ptexIdx, ///< ptex face index
|
||||
numLocations; ///< number of (u,v) coordinates in the array
|
||||
|
||||
float const * s, ///< array of u coordinates
|
||||
REAL const * s, ///< array of u coordinates
|
||||
* t; ///< array of v coordinates
|
||||
};
|
||||
|
||||
@ -221,15 +228,101 @@ public:
|
||||
///
|
||||
/// @param options Options controlling the creation of the table
|
||||
///
|
||||
static LimitStencilTable const * Create(TopologyRefiner const & refiner,
|
||||
LocationArrayVec const & locationArrays,
|
||||
StencilTable const * cvStencils=0,
|
||||
PatchTable const * patchTable=0,
|
||||
Options options=Options());
|
||||
static LimitStencilTableReal<REAL> const * Create(
|
||||
TopologyRefiner const & refiner,
|
||||
LocationArrayVec const & locationArrays,
|
||||
StencilTableReal<REAL> const * cvStencils = 0,
|
||||
PatchTable const * patchTable = 0,
|
||||
Options options = Options());
|
||||
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Public wrapper classes for the templates
|
||||
//
|
||||
class Stencil;
|
||||
class StencilTable;
|
||||
|
||||
/// \brief Stencil table factory class wrapping the template for compatibility.
|
||||
///
|
||||
class StencilTableFactory : public StencilTableFactoryReal<float> {
|
||||
private:
|
||||
typedef StencilTableFactoryReal<float> BaseFactory;
|
||||
typedef StencilTableReal<float> BaseTable;
|
||||
|
||||
public:
|
||||
static StencilTable const * Create(
|
||||
TopologyRefiner const & refiner, Options options = Options()) {
|
||||
|
||||
return static_cast<StencilTable const *>(
|
||||
BaseFactory::Create(refiner, options));
|
||||
}
|
||||
|
||||
static StencilTable const * Create(
|
||||
int numTables, StencilTable const ** tables) {
|
||||
|
||||
return static_cast<StencilTable const *>(
|
||||
BaseFactory::Create(numTables,
|
||||
reinterpret_cast<BaseTable const **>(tables)));
|
||||
}
|
||||
|
||||
static StencilTable const * AppendLocalPointStencilTable(
|
||||
TopologyRefiner const &refiner,
|
||||
StencilTable const *baseStencilTable,
|
||||
StencilTable const *localPointStencilTable,
|
||||
bool factorize = true) {
|
||||
|
||||
return static_cast<StencilTable const *>(
|
||||
BaseFactory::AppendLocalPointStencilTable(refiner,
|
||||
static_cast<BaseTable const *>(baseStencilTable),
|
||||
static_cast<BaseTable const *>(localPointStencilTable),
|
||||
factorize));
|
||||
}
|
||||
|
||||
static StencilTable const * AppendLocalPointStencilTableFaceVarying(
|
||||
TopologyRefiner const &refiner,
|
||||
StencilTable const *baseStencilTable,
|
||||
StencilTable const *localPointStencilTable,
|
||||
int channel = 0,
|
||||
bool factorize = true) {
|
||||
|
||||
return static_cast<StencilTable const *>(
|
||||
BaseFactory::AppendLocalPointStencilTableFaceVarying(refiner,
|
||||
static_cast<BaseTable const *>(baseStencilTable),
|
||||
static_cast<BaseTable const *>(localPointStencilTable),
|
||||
channel, factorize));
|
||||
}
|
||||
};
|
||||
|
||||
class LimitStencil;
|
||||
class LimitStencilTable;
|
||||
|
||||
/// \brief Stencil table factory class wrapping the template for compatibility.
|
||||
///
|
||||
class LimitStencilTableFactory : public LimitStencilTableFactoryReal<float> {
|
||||
private:
|
||||
typedef LimitStencilTableFactoryReal<float> BaseFactory;
|
||||
typedef LimitStencilTableReal<float> BaseTable;
|
||||
|
||||
public:
|
||||
static LimitStencilTable const * Create(
|
||||
TopologyRefiner const & refiner,
|
||||
LocationArrayVec const & locationArrays,
|
||||
LimitStencilTable const * cvStencils = 0,
|
||||
PatchTable const * patchTable = 0,
|
||||
Options options = Options()) {
|
||||
|
||||
return static_cast<LimitStencilTable const *>(
|
||||
BaseFactory::Create(
|
||||
refiner,
|
||||
locationArrays,
|
||||
static_cast<BaseTable const *>(cvStencils),
|
||||
patchTable,
|
||||
options));
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace Far
|
||||
|
||||
} // end namespace OPENSUBDIV_VERSION
|
||||
|
@ -42,6 +42,7 @@ namespace Far { namespace internal { class FeatureMask; } }
|
||||
|
||||
namespace Far {
|
||||
|
||||
template <typename REAL> class PrimvarRefinerReal;
|
||||
template <class MESH> class TopologyRefinerFactory;
|
||||
|
||||
///
|
||||
@ -212,7 +213,8 @@ protected:
|
||||
friend class PatchTableBuilder;
|
||||
friend class PatchBuilder;
|
||||
friend class PtexIndices;
|
||||
friend class PrimvarRefiner;
|
||||
template <typename REAL>
|
||||
friend class PrimvarRefinerReal;
|
||||
|
||||
Vtr::internal::Level & getLevel(int l) { return *_levels[l]; }
|
||||
Vtr::internal::Level const & getLevel(int l) const { return *_levels[l]; }
|
||||
|
Loading…
Reference in New Issue
Block a user