mirror of
https://github.com/PixarAnimationStudios/OpenSubdiv
synced 2024-11-12 15:10:33 +00:00
Merge pull request #1037 from barfowl/far_stencil_table_ptr
Simplify the private PatchTable::StencilTableHandler class
This commit is contained in:
commit
bf38091ac3
@ -66,25 +66,59 @@ PatchTable::PatchTable(PatchTable const & src) :
|
||||
_varyingPrecisionIsDouble(src._varyingPrecisionIsDouble),
|
||||
_faceVaryingPrecisionIsDouble(src._faceVaryingPrecisionIsDouble) {
|
||||
|
||||
if (src._localPointStencils.IsSet()) {
|
||||
_localPointStencils = src._localPointStencils.Clone();
|
||||
if (src._localPointStencils) {
|
||||
if (src._vertexPrecisionIsDouble) {
|
||||
_localPointStencils.Set(
|
||||
new StencilTableReal<double>(*src._localPointStencils.Get<double>()));
|
||||
} else {
|
||||
_localPointStencils.Set(
|
||||
new StencilTableReal<float>(*src._localPointStencils.Get<float>()));
|
||||
}
|
||||
}
|
||||
if (src._localPointVaryingStencils.IsSet()) {
|
||||
_localPointVaryingStencils = src._localPointVaryingStencils.Clone();
|
||||
if (src._localPointVaryingStencils) {
|
||||
if (src._varyingPrecisionIsDouble) {
|
||||
_localPointVaryingStencils.Set(
|
||||
new StencilTableReal<double>(*src._localPointVaryingStencils.Get<double>()));
|
||||
} else {
|
||||
_localPointVaryingStencils.Set(
|
||||
new StencilTableReal<float>(*src._localPointVaryingStencils.Get<float>()));
|
||||
}
|
||||
}
|
||||
if (! src._localPointFaceVaryingStencils.empty()) {
|
||||
_localPointFaceVaryingStencils.resize(src._localPointFaceVaryingStencils.size());
|
||||
for (int fvc=0; fvc<(int)_localPointFaceVaryingStencils.size(); ++fvc) {
|
||||
_localPointFaceVaryingStencils[fvc] = src._localPointFaceVaryingStencils[fvc].Clone();
|
||||
if (src._localPointFaceVaryingStencils[fvc]) {
|
||||
if (src._faceVaryingPrecisionIsDouble) {
|
||||
_localPointFaceVaryingStencils[fvc].Set(new StencilTableReal<double>(
|
||||
*src._localPointFaceVaryingStencils[fvc].Get<double>()));
|
||||
} else {
|
||||
_localPointFaceVaryingStencils[fvc].Set(new StencilTableReal<float>(
|
||||
*src._localPointFaceVaryingStencils[fvc].Get<float>()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PatchTable::~PatchTable() {
|
||||
_localPointStencils.Delete();
|
||||
_localPointVaryingStencils.Delete();
|
||||
if (_vertexPrecisionIsDouble) {
|
||||
delete _localPointStencils.Get<double>();
|
||||
} else {
|
||||
delete _localPointStencils.Get<float>();
|
||||
}
|
||||
|
||||
if (_varyingPrecisionIsDouble) {
|
||||
delete _localPointVaryingStencils.Get<double>();
|
||||
} else {
|
||||
delete _localPointVaryingStencils.Get<float>();
|
||||
}
|
||||
|
||||
for (int fvc=0; fvc<(int)_localPointFaceVaryingStencils.size(); ++fvc) {
|
||||
_localPointFaceVaryingStencils[fvc].Delete();
|
||||
if (_faceVaryingPrecisionIsDouble) {
|
||||
delete _localPointFaceVaryingStencils[fvc].Get<double>();
|
||||
} else {
|
||||
delete _localPointFaceVaryingStencils[fvc].Get<float>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -365,17 +399,25 @@ PatchTable::GetSingleCreasePatchSharpnessValue(int arrayIndex, int patchIndex) c
|
||||
|
||||
int
|
||||
PatchTable::GetNumLocalPoints() const {
|
||||
return _localPointStencils.IsSet() ? _localPointStencils.Size() : 0;
|
||||
if (!_localPointStencils) return 0;
|
||||
return _vertexPrecisionIsDouble
|
||||
? _localPointStencils.Get<double>()->GetNumStencils()
|
||||
: _localPointStencils.Get<float>()->GetNumStencils();
|
||||
}
|
||||
int
|
||||
PatchTable::GetNumLocalPointsVarying() const {
|
||||
return _localPointVaryingStencils.IsSet() ? _localPointVaryingStencils.Size() : 0;
|
||||
if (!_localPointVaryingStencils) return 0;
|
||||
return _varyingPrecisionIsDouble
|
||||
? _localPointVaryingStencils.Get<double>()->GetNumStencils()
|
||||
: _localPointVaryingStencils.Get<float>()->GetNumStencils();
|
||||
}
|
||||
int
|
||||
PatchTable::GetNumLocalPointsFaceVarying(int channel) const {
|
||||
if (channel>=0 && channel<(int)_localPointFaceVaryingStencils.size()) {
|
||||
return _localPointFaceVaryingStencils[channel].IsSet() ?
|
||||
_localPointFaceVaryingStencils[channel].Size() : 0;
|
||||
if (!_localPointFaceVaryingStencils[channel]) return 0;
|
||||
return _faceVaryingPrecisionIsDouble
|
||||
? _localPointFaceVaryingStencils[channel].Get<double>()->GetNumStencils()
|
||||
: _localPointFaceVaryingStencils[channel].Get<float>()->GetNumStencils();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -597,54 +597,34 @@ private:
|
||||
|
||||
private:
|
||||
//
|
||||
// Private class to manage stencil table pointers of varying precision
|
||||
// Simple private class to hold stencil table pointers of varying precision,
|
||||
// where the discriminant of the precision is external.
|
||||
//
|
||||
// This implementation is still up for debate -- could be improved or
|
||||
// could be entirely replaced...
|
||||
// NOTE that this is a simple pointer container and NOT a smart pointer that
|
||||
// manages the ownership of the object referred to by it.
|
||||
//
|
||||
class StencilTableHandler {
|
||||
class StencilTablePtr {
|
||||
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;
|
||||
|
||||
public:
|
||||
StencilTablePtr() { _fPtr = 0; }
|
||||
StencilTablePtr(float_type * ptr) { _fPtr = ptr; }
|
||||
StencilTablePtr(double_type * ptr) { _dPtr = ptr; }
|
||||
|
||||
operator bool() const { return _fPtr != 0; }
|
||||
|
||||
void Set() { _fPtr = 0; }
|
||||
void Set(float_type * ptr) { _fPtr = ptr; }
|
||||
void Set(double_type * ptr) { _dPtr = ptr; }
|
||||
|
||||
template <typename REAL> StencilTableReal<REAL> * Get() const;
|
||||
};
|
||||
|
||||
private:
|
||||
@ -671,8 +651,8 @@ private:
|
||||
QuadOffsetsTable _quadOffsetsTable; // Quad offsets (for Gregory patches)
|
||||
VertexValenceTable _vertexValenceTable; // Vertex valence table (for Gregory patches)
|
||||
|
||||
StencilTableHandler _localPointStencils; // local point conversion stencils
|
||||
StencilTableHandler _localPointVaryingStencils; // local point varying stencils
|
||||
StencilTablePtr _localPointStencils; // local point conversion stencils
|
||||
StencilTablePtr _localPointVaryingStencils; // local point varying stencils
|
||||
|
||||
//
|
||||
// Varying data
|
||||
@ -686,7 +666,7 @@ private:
|
||||
//
|
||||
FVarPatchChannelVector _fvarChannels;
|
||||
|
||||
std::vector<StencilTableHandler> _localPointFaceVaryingStencils;
|
||||
std::vector<StencilTablePtr> _localPointFaceVaryingStencils;
|
||||
|
||||
//
|
||||
// 'single-crease' patch sharpness tables
|
||||
@ -712,10 +692,10 @@ private:
|
||||
// Template specializations for float/double -- to be defined before used:
|
||||
//
|
||||
template <> inline StencilTableReal<float> *
|
||||
PatchTable::StencilTableHandler::Get<float>() const { return _fPtr; }
|
||||
PatchTable::StencilTablePtr::Get<float>() const { return _fPtr; }
|
||||
|
||||
template <> inline StencilTableReal<double> *
|
||||
PatchTable::StencilTableHandler::Get<double>() const { return _dPtr; }
|
||||
PatchTable::StencilTablePtr::Get<double>() const { return _dPtr; }
|
||||
|
||||
template <> inline bool
|
||||
PatchTable::IsLocalPointStencilPrecision<float>() const {
|
||||
@ -797,7 +777,7 @@ template <class T>
|
||||
inline void
|
||||
PatchTable::ComputeLocalPointValues(T const *src, T *dst) const {
|
||||
assert(IsLocalPointStencilPrecision<float>());
|
||||
if (_localPointStencils.IsSet()) {
|
||||
if (_localPointStencils) {
|
||||
_localPointStencils.Get<float>()->UpdateValues(src, dst);
|
||||
}
|
||||
}
|
||||
@ -806,7 +786,7 @@ template <class T>
|
||||
inline void
|
||||
PatchTable::ComputeLocalPointValuesVarying(T const *src, T *dst) const {
|
||||
assert(IsLocalPointVaryingStencilPrecision<float>());
|
||||
if (_localPointVaryingStencils.IsSet()) {
|
||||
if (_localPointVaryingStencils) {
|
||||
_localPointVaryingStencils.Get<float>()->UpdateValues(src, dst);
|
||||
}
|
||||
}
|
||||
@ -816,7 +796,7 @@ inline void
|
||||
PatchTable::ComputeLocalPointValuesFaceVarying(T const *src, T *dst, int channel) const {
|
||||
assert(IsLocalPointFaceVaryingStencilPrecision<float>());
|
||||
if (channel >= 0 && channel < (int)_localPointFaceVaryingStencils.size()) {
|
||||
if (_localPointFaceVaryingStencils[channel].IsSet()) {
|
||||
if (_localPointFaceVaryingStencils[channel]) {
|
||||
_localPointFaceVaryingStencils[channel].Get<float>()->UpdateValues(src, dst);
|
||||
}
|
||||
}
|
||||
|
@ -115,7 +115,7 @@ public:
|
||||
PatchTable * GetPatchTable() const { return _table; };
|
||||
|
||||
private:
|
||||
typedef PatchTable::StencilTableHandler StencilTableHandler;
|
||||
typedef PatchTable::StencilTablePtr StencilTablePtr;
|
||||
|
||||
// Simple struct to store <face,level> pair for a patch:
|
||||
struct PatchTuple {
|
||||
@ -195,12 +195,17 @@ private:
|
||||
int sourcePointOffset,
|
||||
Index patchPoints[]);
|
||||
|
||||
StencilTableHandler AcquireStencilTable() {
|
||||
return acquireStencilTable(_stencilTable);
|
||||
StencilTablePtr AcquireStencilTable() {
|
||||
return _options.doubleStencilTable
|
||||
? acquireStencilTable<double>(_stencilTable)
|
||||
: acquireStencilTable<float>(_stencilTable);
|
||||
}
|
||||
|
||||
private:
|
||||
// Internal methods:
|
||||
template <typename REAL>
|
||||
void initializeStencilTable(int numLocalPointsExpected);
|
||||
|
||||
template <typename REAL>
|
||||
void appendLocalPointStencil(SparseMatrix<REAL> const & conversionMatrix,
|
||||
int stencilRow,
|
||||
@ -220,7 +225,8 @@ private:
|
||||
Index const sourcePoints[],
|
||||
int sourcePointOffset);
|
||||
|
||||
StencilTableHandler acquireStencilTable(StencilTableHandler& stencilTableMember);
|
||||
template <typename REAL>
|
||||
StencilTablePtr acquireStencilTable(StencilTablePtr& stencilTableMember);
|
||||
|
||||
Index findSharedCornerPoint(int levelIndex, Index valueIndex,
|
||||
Index newIndex);
|
||||
@ -239,16 +245,18 @@ private:
|
||||
std::vector<IndexVector> _sharedCornerPoints;
|
||||
std::vector<IndexVector> _sharedEdgePoints;
|
||||
|
||||
StencilTableHandler _stencilTable;
|
||||
StencilTablePtr _stencilTable;
|
||||
|
||||
// This was hopefully transitional but will persist -- the should be
|
||||
// no need for Varying local points or stencils associated with them.
|
||||
public:
|
||||
StencilTableHandler AcquireStencilTableVarying() {
|
||||
return acquireStencilTable(_stencilTableVarying);
|
||||
StencilTablePtr AcquireStencilTableVarying() {
|
||||
return _options.doubleStencilTable
|
||||
? acquireStencilTable<double>(_stencilTableVarying)
|
||||
: acquireStencilTable<float>(_stencilTableVarying);
|
||||
}
|
||||
|
||||
StencilTableHandler _stencilTableVarying;
|
||||
StencilTablePtr _stencilTableVarying;
|
||||
};
|
||||
|
||||
private:
|
||||
@ -1417,17 +1425,16 @@ PatchTableBuilder::LocalPointHelper::LocalPointHelper(
|
||||
|
||||
if (_options.createStencilTable) {
|
||||
if (_options.doubleStencilTable) {
|
||||
_stencilTable.Set(new StencilTableReal<double>(0));
|
||||
if (_options.createVaryingTable) {
|
||||
_stencilTableVarying.Set(new StencilTableReal<double>(0));
|
||||
}
|
||||
initializeStencilTable<double>(numLocalPointsExpected);
|
||||
} else {
|
||||
_stencilTable.Set(new StencilTableReal<float>(0));
|
||||
if (_options.createVaryingTable) {
|
||||
_stencilTableVarying.Set(new StencilTableReal<float>(0));
|
||||
}
|
||||
initializeStencilTable<float>(numLocalPointsExpected);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename REAL>
|
||||
void
|
||||
PatchTableBuilder::LocalPointHelper::initializeStencilTable(int numLocalPointsExpected) {
|
||||
|
||||
//
|
||||
// Reserving space for the local-point stencils has been a source of
|
||||
@ -1438,65 +1445,63 @@ 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.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
|
||||
StencilTableReal<REAL> * stencilTable = new StencilTableReal<REAL>(0);
|
||||
StencilTableReal<REAL> * varyingTable = _options.createVaryingTable
|
||||
? new StencilTableReal<REAL>(0) : 0;
|
||||
|
||||
size_t numStencilsExpected = numLocalPointsExpected;
|
||||
size_t numStencilEntriesExpected = numStencilsExpected * AvgEntriesPerStencil;
|
||||
// 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
|
||||
|
||||
size_t numEntriesToReserve = std::min(numStencilEntriesExpected,
|
||||
MaxEntriesToReserve);
|
||||
if (numEntriesToReserve) {
|
||||
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
|
||||
if (_stencilTableVarying.IsDouble()) {
|
||||
_stencilTableVarying.Get<double>()->reserve(
|
||||
(int)numStencilsExpected, (int)numStencilsExpected);
|
||||
} else {
|
||||
_stencilTableVarying.Get<float>()->reserve(
|
||||
(int)numStencilsExpected, (int)numStencilsExpected);
|
||||
}
|
||||
}
|
||||
size_t numStencilsExpected = numLocalPointsExpected;
|
||||
size_t numStencilEntriesExpected = numStencilsExpected * AvgEntriesPerStencil;
|
||||
|
||||
size_t numEntriesToReserve = std::min(numStencilEntriesExpected,
|
||||
MaxEntriesToReserve);
|
||||
if (numEntriesToReserve) {
|
||||
stencilTable->reserve(
|
||||
(int)numStencilsExpected, (int)numEntriesToReserve);
|
||||
|
||||
if (varyingTable) {
|
||||
// Varying stencils have only one entry per point
|
||||
varyingTable->reserve(
|
||||
(int)numStencilsExpected, (int)numStencilsExpected);
|
||||
}
|
||||
}
|
||||
|
||||
_stencilTable.Set(stencilTable);
|
||||
_stencilTableVarying.Set(varyingTable);
|
||||
}
|
||||
|
||||
PatchTableBuilder::StencilTableHandler
|
||||
template <typename REAL>
|
||||
PatchTableBuilder::StencilTablePtr
|
||||
PatchTableBuilder::LocalPointHelper::acquireStencilTable(
|
||||
StencilTableHandler& stencilTableMember) {
|
||||
StencilTablePtr& stencilTableMember) {
|
||||
|
||||
StencilTableHandler stencilTable = stencilTableMember;
|
||||
StencilTableReal<REAL> * stencilTable = stencilTableMember.Get<REAL>();
|
||||
|
||||
if (stencilTable.IsSet()) {
|
||||
if (stencilTable.Size() > 0) {
|
||||
if (stencilTable.IsDouble()) {
|
||||
stencilTable.Get<double>()->finalize();
|
||||
} else {
|
||||
stencilTable.Get<float>()->finalize();
|
||||
}
|
||||
if (stencilTable) {
|
||||
if (stencilTable->GetNumStencils() > 0) {
|
||||
stencilTable->finalize();
|
||||
} else {
|
||||
stencilTable.Delete();
|
||||
stencilTable.Clear();
|
||||
delete stencilTable;
|
||||
stencilTable = 0;
|
||||
}
|
||||
}
|
||||
|
||||
stencilTableMember.Clear();
|
||||
return stencilTable;
|
||||
stencilTableMember.Set();
|
||||
return StencilTablePtr(stencilTable);
|
||||
}
|
||||
|
||||
PatchTableBuilder::LocalPointHelper::~LocalPointHelper() {
|
||||
|
||||
_stencilTable.Delete();
|
||||
_stencilTableVarying.Delete();
|
||||
if (_options.doubleStencilTable) {
|
||||
delete _stencilTable.Get<double>();
|
||||
delete _stencilTableVarying.Get<double>();
|
||||
} else {
|
||||
delete _stencilTable.Get<float>();
|
||||
delete _stencilTableVarying.Get<float>();
|
||||
}
|
||||
}
|
||||
|
||||
Index
|
||||
@ -1727,11 +1732,11 @@ PatchTableBuilder::LocalPointHelper::AppendLocalPatchPoints(
|
||||
bool shareLocalPointsForThisPatch = (shareBitsPerPoint != 0);
|
||||
|
||||
int const * varyingIndices = 0;
|
||||
if (_stencilTableVarying.IsSet()) {
|
||||
if (_stencilTableVarying) {
|
||||
varyingIndices = GetVaryingIndicesPerType(patchType);
|
||||
}
|
||||
|
||||
bool applyVertexStencils = _stencilTable.IsSet();
|
||||
bool applyVertexStencils = (_stencilTable.Get<REAL>() != 0);
|
||||
bool applyVaryingStencils = (varyingIndices != 0);
|
||||
|
||||
//
|
||||
|
Loading…
Reference in New Issue
Block a user