2014-09-19 00:48:34 +00:00
|
|
|
//
|
|
|
|
// Copyright 2013 Pixar
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "Apache License")
|
|
|
|
// with the following modification; you may not use this file except in
|
|
|
|
// compliance with the Apache License and the following modification to it:
|
|
|
|
// Section 6. Trademarks. is deleted and replaced with:
|
|
|
|
//
|
|
|
|
// 6. Trademarks. This License does not grant permission to use the trade
|
|
|
|
// names, trademarks, service marks, or product names of the Licensor
|
|
|
|
// and its affiliates, except as required to comply with Section 4(c) of
|
|
|
|
// the License and to reproduce the content of the NOTICE file.
|
|
|
|
//
|
|
|
|
// You may obtain a copy of the Apache License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the Apache License with the above modification is
|
|
|
|
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
|
|
// KIND, either express or implied. See the Apache License for the specific
|
|
|
|
// language governing permissions and limitations under the Apache License.
|
|
|
|
//
|
|
|
|
|
|
|
|
#include "../far/patchTables.h"
|
2014-11-11 19:27:25 +00:00
|
|
|
#include "../far/stencilTables.h"
|
2014-09-19 00:48:34 +00:00
|
|
|
|
|
|
|
#include <cstring>
|
|
|
|
|
|
|
|
namespace OpenSubdiv {
|
|
|
|
namespace OPENSUBDIV_VERSION {
|
|
|
|
|
2014-10-09 21:48:50 +00:00
|
|
|
namespace Far {
|
|
|
|
|
2014-11-25 20:41:19 +00:00
|
|
|
PatchTables::PatchTables(int maxvalence) :
|
|
|
|
_maxValence(maxvalence), _endcapStencilTables(0), _fvarPatchTables(0) { }
|
|
|
|
|
|
|
|
// Copy constructor
|
|
|
|
// XXXX manuelk we need to eliminate this constructor (C++11 smart pointers)
|
|
|
|
PatchTables::PatchTables(PatchTables const & src) :
|
|
|
|
_maxValence(src._maxValence),
|
|
|
|
_numPtexFaces(src._numPtexFaces),
|
|
|
|
_patchArrays(src._patchArrays),
|
|
|
|
_patchVerts(src._patchVerts),
|
|
|
|
_paramTable(src._paramTable),
|
|
|
|
#ifdef ENDCAP_TOPOPOLGY
|
|
|
|
_endcapTopology(src._endcapTopology),
|
|
|
|
#endif
|
|
|
|
_quadOffsetsTable(src._quadOffsetsTable),
|
|
|
|
_vertexValenceTable(src._vertexValenceTable),
|
|
|
|
_sharpnessIndices(src._sharpnessIndices),
|
|
|
|
_sharpnessValues(src._sharpnessValues) {
|
|
|
|
|
|
|
|
_endcapStencilTables = src._endcapStencilTables ?
|
|
|
|
new StencilTables(*src._endcapStencilTables) : 0;
|
|
|
|
|
|
|
|
_fvarPatchTables = src._fvarPatchTables ?
|
|
|
|
new FVarPatchTables(*src._fvarPatchTables) : 0;
|
2014-10-09 21:48:50 +00:00
|
|
|
}
|
|
|
|
|
2014-11-11 19:27:25 +00:00
|
|
|
PatchTables::~PatchTables() {
|
|
|
|
delete _endcapStencilTables;
|
|
|
|
delete _fvarPatchTables;
|
|
|
|
}
|
|
|
|
|
2014-10-09 21:48:50 +00:00
|
|
|
//
|
2014-11-25 20:41:19 +00:00
|
|
|
// PatchArrays
|
2014-10-09 21:48:50 +00:00
|
|
|
//
|
|
|
|
|
2014-11-25 20:41:19 +00:00
|
|
|
struct PatchTables::PatchArray {
|
2014-10-09 21:48:50 +00:00
|
|
|
|
2014-11-25 20:41:19 +00:00
|
|
|
PatchArray(PatchDescriptor d, int np, Index v, Index p, Index qo) :
|
|
|
|
desc(d), numPatches(np), vertIndex(v),
|
|
|
|
patchIndex(p), quadOffsetIndex (qo) { }
|
2014-10-09 21:48:50 +00:00
|
|
|
|
2014-11-25 20:41:19 +00:00
|
|
|
PatchDescriptor desc; // type of patches in the array
|
2014-10-09 21:48:50 +00:00
|
|
|
|
2014-11-25 20:41:19 +00:00
|
|
|
int numPatches; // number of patches in the array
|
2014-10-09 21:48:50 +00:00
|
|
|
|
2014-11-25 20:41:19 +00:00
|
|
|
Index vertIndex, // index to the first control vertex
|
|
|
|
patchIndex, // index of the first patch in the array
|
|
|
|
quadOffsetIndex; // index of the first quad offset entry
|
|
|
|
};
|
2014-10-09 21:48:50 +00:00
|
|
|
|
2014-11-25 20:41:19 +00:00
|
|
|
inline PatchTables::PatchArray &
|
|
|
|
PatchTables::getPatchArray(Index arrayIndex) {
|
|
|
|
assert(arrayIndex<(Index)GetNumPatchArrays());
|
|
|
|
return _patchArrays[arrayIndex];
|
|
|
|
}
|
2014-10-09 21:48:50 +00:00
|
|
|
|
2014-11-25 20:41:19 +00:00
|
|
|
inline PatchTables::PatchArray const &
|
|
|
|
PatchTables::getPatchArray(Index arrayIndex) const {
|
|
|
|
assert(arrayIndex<(Index)GetNumPatchArrays());
|
|
|
|
return _patchArrays[arrayIndex];
|
2014-10-09 21:48:50 +00:00
|
|
|
}
|
|
|
|
|
2014-11-25 20:41:19 +00:00
|
|
|
void
|
|
|
|
PatchTables::reservePatchArrays(int numPatchArrays) {
|
|
|
|
_patchArrays.reserve(numPatchArrays);
|
|
|
|
}
|
2014-10-09 21:48:50 +00:00
|
|
|
|
2014-11-25 20:41:19 +00:00
|
|
|
inline int
|
|
|
|
getPatchSize(PatchDescriptor desc) {
|
|
|
|
int size = desc.GetNumControlVertices();
|
|
|
|
// XXXX manuelk we do not store the topology for Gregory Basis
|
|
|
|
// patch types yet - so point to the 4 corners of the 0-ring
|
|
|
|
if (desc.GetType() == PatchDescriptor::GREGORY_BASIS) {
|
|
|
|
size = 4;
|
2014-10-09 21:48:50 +00:00
|
|
|
}
|
2014-11-25 20:41:19 +00:00
|
|
|
return size;
|
2014-10-09 21:48:50 +00:00
|
|
|
}
|
|
|
|
|
2014-11-25 20:41:19 +00:00
|
|
|
void
|
|
|
|
PatchTables::pushPatchArray(PatchDescriptor desc, int npatches,
|
|
|
|
Index * vidx, Index * pidx, Index * qoidx) {
|
|
|
|
|
|
|
|
if (npatches>0) {
|
|
|
|
_patchArrays.push_back(PatchArray(
|
|
|
|
desc, npatches, *vidx, *pidx, qoidx ? *qoidx : 0));
|
|
|
|
int nverts = getPatchSize(desc);
|
|
|
|
*vidx += npatches * nverts;
|
|
|
|
*pidx += npatches;
|
|
|
|
if (qoidx) {
|
|
|
|
*qoidx += (desc.GetType() == PatchDescriptor::GREGORY) ?
|
|
|
|
npatches*nverts : 0;
|
|
|
|
}
|
2014-10-09 21:48:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-28 23:50:23 +00:00
|
|
|
Index
|
|
|
|
PatchTables::getPatchIndex(int arrayIndex, int patchIndex) const {
|
|
|
|
PatchArray const & pa = getPatchArray(arrayIndex);
|
|
|
|
assert(patchIndex<pa.numPatches);
|
|
|
|
return pa.patchIndex + patchIndex;
|
|
|
|
}
|
2014-11-25 20:41:19 +00:00
|
|
|
Index *
|
|
|
|
PatchTables::getSharpnessIndices(int arrayIndex) {
|
|
|
|
return &_sharpnessIndices[getPatchArray(arrayIndex).patchIndex];
|
|
|
|
}
|
2014-10-09 21:48:50 +00:00
|
|
|
|
2014-11-25 20:41:19 +00:00
|
|
|
float *
|
|
|
|
PatchTables::getSharpnessValues(int arrayIndex) {
|
|
|
|
return &_sharpnessValues[getPatchArray(arrayIndex).patchIndex];
|
|
|
|
}
|
2014-10-09 21:48:50 +00:00
|
|
|
|
2014-11-25 20:41:19 +00:00
|
|
|
PatchDescriptor
|
|
|
|
PatchTables::GetPatchDescriptor(PatchHandle const & handle) const {
|
|
|
|
return getPatchArray(handle.arrayIndex).desc;
|
|
|
|
}
|
2014-10-09 21:48:50 +00:00
|
|
|
|
2014-11-25 20:41:19 +00:00
|
|
|
PatchDescriptor
|
|
|
|
PatchTables::GetPatchArrayDescriptor(int arrayIndex) const {
|
|
|
|
return getPatchArray(arrayIndex).desc;
|
|
|
|
}
|
2014-10-09 21:48:50 +00:00
|
|
|
|
2014-11-25 20:41:19 +00:00
|
|
|
int
|
|
|
|
PatchTables::GetNumPatchArrays() const {
|
|
|
|
return (int)_patchArrays.size();
|
|
|
|
}
|
|
|
|
int
|
|
|
|
PatchTables::GetNumPatches(int arrayIndex) const {
|
|
|
|
return getPatchArray(arrayIndex).numPatches;
|
|
|
|
}
|
|
|
|
int
|
|
|
|
PatchTables::GetNumControlVertices(int arrayIndex) const {
|
|
|
|
PatchArray const & pa = getPatchArray(arrayIndex);
|
|
|
|
return pa.numPatches * getPatchSize(pa.desc);
|
|
|
|
}
|
2014-10-09 21:48:50 +00:00
|
|
|
|
2014-11-25 20:41:19 +00:00
|
|
|
IndexArray
|
|
|
|
PatchTables::getPatchArrayVertices(int arrayIndex) {
|
|
|
|
PatchArray const & pa = getPatchArray(arrayIndex);
|
|
|
|
int size = getPatchSize(pa.desc);
|
|
|
|
assert(pa.vertIndex<(Index)_patchVerts.size());
|
|
|
|
return IndexArray(&_patchVerts[pa.vertIndex], pa.numPatches * size);
|
|
|
|
}
|
2014-12-15 18:23:13 +00:00
|
|
|
ConstIndexArray
|
2014-11-25 20:41:19 +00:00
|
|
|
PatchTables::GetPatchArrayVertices(int arrayIndex) const {
|
|
|
|
PatchArray const & pa = getPatchArray(arrayIndex);
|
|
|
|
int size = getPatchSize(pa.desc);
|
|
|
|
assert(pa.vertIndex<(Index)_patchVerts.size());
|
2014-12-15 18:23:13 +00:00
|
|
|
return ConstIndexArray(&_patchVerts[pa.vertIndex], pa.numPatches * size);
|
2014-11-25 20:41:19 +00:00
|
|
|
}
|
2014-10-09 21:48:50 +00:00
|
|
|
|
2014-12-15 18:23:13 +00:00
|
|
|
ConstIndexArray
|
2014-11-25 20:41:19 +00:00
|
|
|
PatchTables::GetPatchVertices(PatchHandle const & handle) const {
|
|
|
|
PatchArray const & pa = getPatchArray(handle.arrayIndex);
|
|
|
|
|
|
|
|
Index vert = pa.vertIndex;
|
|
|
|
// XXXX manuelk we do not store the topology for Gregory Basis
|
|
|
|
// patch types yet - so point to the 4 corners of the 0-ring
|
|
|
|
vert += (pa.desc.GetType() == PatchDescriptor::GREGORY_BASIS) ?
|
|
|
|
handle.vertIndex / 5 : handle.vertIndex;
|
|
|
|
assert(vert<(Index)_patchVerts.size());
|
2014-12-15 18:23:13 +00:00
|
|
|
return ConstIndexArray(&_patchVerts[vert], getPatchSize(pa.desc));
|
2014-11-25 20:41:19 +00:00
|
|
|
}
|
2014-12-15 18:23:13 +00:00
|
|
|
ConstIndexArray
|
2014-11-25 20:41:19 +00:00
|
|
|
PatchTables::GetPatchVertices(int arrayIndex, int patchIndex) const {
|
|
|
|
PatchArray const & pa = getPatchArray(arrayIndex);
|
|
|
|
int size = getPatchSize(pa.desc);
|
|
|
|
assert((pa.vertIndex + patchIndex*size)<(Index)_patchVerts.size());
|
2014-12-15 18:23:13 +00:00
|
|
|
return ConstIndexArray(&_patchVerts[pa.vertIndex + patchIndex*size], size);
|
2014-11-25 20:41:19 +00:00
|
|
|
}
|
2014-10-09 21:48:50 +00:00
|
|
|
|
2014-11-25 20:41:19 +00:00
|
|
|
PatchParam
|
|
|
|
PatchTables::GetPatchParam(PatchHandle const & handle) const {
|
|
|
|
assert(handle.patchIndex < (Index)_paramTable.size());
|
|
|
|
return _paramTable[handle.patchIndex];
|
|
|
|
}
|
|
|
|
PatchParam
|
|
|
|
PatchTables::GetPatchParam(int arrayIndex, int patchIndex) const {
|
|
|
|
PatchArray const & pa = getPatchArray(arrayIndex);
|
|
|
|
assert((pa.patchIndex + patchIndex) < (int)_paramTable.size());
|
|
|
|
return _paramTable[pa.patchIndex + patchIndex];
|
|
|
|
}
|
|
|
|
PatchParamArray
|
|
|
|
PatchTables::getPatchParams(int arrayIndex) {
|
|
|
|
PatchArray const & pa = getPatchArray(arrayIndex);
|
|
|
|
return PatchParamArray(&_paramTable[pa.patchIndex], pa.numPatches);
|
|
|
|
}
|
2014-12-15 18:23:13 +00:00
|
|
|
ConstPatchParamArray const
|
2014-11-25 20:41:19 +00:00
|
|
|
PatchTables::GetPatchParams(int arrayIndex) const {
|
|
|
|
PatchArray const & pa = getPatchArray(arrayIndex);
|
2014-12-15 18:23:13 +00:00
|
|
|
return ConstPatchParamArray(&_paramTable[pa.patchIndex], pa.numPatches);
|
2014-11-25 20:41:19 +00:00
|
|
|
}
|
2014-10-09 21:48:50 +00:00
|
|
|
|
2014-11-25 20:41:19 +00:00
|
|
|
float
|
|
|
|
PatchTables::GetSingleCreasePatchSharpnessValue(PatchHandle const & handle) const {
|
|
|
|
assert((handle.patchIndex) < (int)_sharpnessIndices.size());
|
|
|
|
Index index = _sharpnessIndices[handle.patchIndex];
|
|
|
|
if (index == Vtr::INDEX_INVALID) {
|
|
|
|
return 0.0f;
|
|
|
|
}
|
|
|
|
assert(index < (Index)_sharpnessValues.size());
|
|
|
|
return _sharpnessValues[index];
|
|
|
|
}
|
|
|
|
float
|
|
|
|
PatchTables::GetSingleCreasePatchSharpnessValue(int arrayIndex, int patchIndex) const {
|
|
|
|
PatchArray const & pa = getPatchArray(arrayIndex);
|
|
|
|
assert((pa.patchIndex + patchIndex) < (int)_sharpnessIndices.size());
|
|
|
|
Index index = _sharpnessIndices[pa.patchIndex + patchIndex];
|
|
|
|
if (index == Vtr::INDEX_INVALID) {
|
|
|
|
return 0.0f;
|
|
|
|
}
|
|
|
|
assert(index < (Index)_sharpnessValues.size());
|
|
|
|
return _sharpnessValues[index];
|
|
|
|
}
|
2014-10-13 15:52:09 +00:00
|
|
|
|
2014-12-15 18:23:13 +00:00
|
|
|
PatchTables::ConstQuadOffsetsArray
|
2014-11-25 20:41:19 +00:00
|
|
|
PatchTables::GetPatchQuadOffsets(PatchHandle const & handle) const {
|
|
|
|
PatchArray const & pa = getPatchArray(handle.arrayIndex);
|
2014-12-15 18:23:13 +00:00
|
|
|
return Vtr::ConstArray<unsigned int>(&_quadOffsetsTable[pa.quadOffsetIndex + handle.vertIndex], 4);
|
2014-11-25 20:41:19 +00:00
|
|
|
}
|
2014-10-09 21:48:50 +00:00
|
|
|
|
2014-11-25 20:41:19 +00:00
|
|
|
IndexArray
|
|
|
|
PatchTables::getFVarVerts(int arrayIndex, int channel) {
|
|
|
|
PatchArray const & pa = getPatchArray(arrayIndex);
|
|
|
|
assert(_fvarPatchTables and (channel<(int)_fvarPatchTables->_channels.size()));
|
|
|
|
std::vector<Index> & verts = _fvarPatchTables->_channels[channel].patchVertIndices;
|
|
|
|
int ofs = pa.patchIndex * pa.desc.GetNumFVarControlVertices();
|
|
|
|
return IndexArray(&verts[ofs],pa.numPatches * pa.desc.GetNumFVarControlVertices());
|
2014-10-09 21:48:50 +00:00
|
|
|
}
|
|
|
|
|
2014-11-25 20:41:19 +00:00
|
|
|
bool
|
|
|
|
PatchTables::IsFeatureAdaptive() const {
|
2014-10-09 21:48:50 +00:00
|
|
|
|
2014-11-25 20:41:19 +00:00
|
|
|
// check for presence of tables only used by adaptive patches
|
|
|
|
if (not _vertexValenceTable.empty() or _endcapStencilTables)
|
|
|
|
return true;
|
2014-10-09 21:48:50 +00:00
|
|
|
|
2014-11-25 20:41:19 +00:00
|
|
|
// otherwise, we have to check each patch array
|
|
|
|
for (int i=0; i<GetNumPatchArrays(); ++i) {
|
|
|
|
PatchDescriptor const & desc = _patchArrays[i].desc;
|
|
|
|
if (desc.GetType()>=PatchDescriptor::REGULAR and
|
|
|
|
desc.GetType()<=PatchDescriptor::GREGORY_BASIS) {
|
|
|
|
return true;
|
|
|
|
}
|
2014-10-09 21:48:50 +00:00
|
|
|
}
|
2014-11-25 20:41:19 +00:00
|
|
|
return false;
|
2014-10-09 21:48:50 +00:00
|
|
|
}
|
|
|
|
|
2014-11-25 20:41:19 +00:00
|
|
|
int
|
|
|
|
PatchTables::GetNumPatchesTotal() const {
|
|
|
|
// there is one PatchParam record for each patch in the mesh
|
|
|
|
return (int)_paramTable.size();
|
|
|
|
}
|
2014-10-09 21:48:50 +00:00
|
|
|
|
2014-11-25 20:41:19 +00:00
|
|
|
// Returns the first array of patches matching the descriptor
|
|
|
|
Index
|
|
|
|
PatchTables::findPatchArray(PatchDescriptor desc) {
|
|
|
|
for (int i=0; i<(int)_patchArrays.size(); ++i) {
|
|
|
|
if (_patchArrays[i].desc==desc)
|
|
|
|
return i;
|
2014-10-09 21:48:50 +00:00
|
|
|
}
|
2014-11-25 20:41:19 +00:00
|
|
|
return Vtr::INDEX_INVALID;
|
2014-10-09 21:48:50 +00:00
|
|
|
}
|
|
|
|
|
2014-09-19 00:48:34 +00:00
|
|
|
} // end namespace Far
|
|
|
|
|
|
|
|
} // end namespace OPENSUBDIV_VERSION
|
|
|
|
} // end namespace OpenSubdiv
|