2013-09-11 23:05:14 +00:00
|
|
|
//
|
2013-09-26 19:04:57 +00:00
|
|
|
// Copyright 2013 Pixar
|
2013-09-11 23:05:14 +00:00
|
|
|
//
|
2013-09-26 19:04:57 +00:00
|
|
|
// 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:
|
2013-09-11 23:05:14 +00:00
|
|
|
//
|
2013-09-26 19:04:57 +00:00
|
|
|
// 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.
|
2013-09-11 23:05:14 +00:00
|
|
|
//
|
2013-09-26 19:04:57 +00:00
|
|
|
// You may obtain a copy of the Apache License at
|
2013-09-11 23:05:14 +00:00
|
|
|
//
|
2013-09-26 19:04:57 +00:00
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
2013-09-11 23:05:14 +00:00
|
|
|
//
|
2013-09-26 19:04:57 +00:00
|
|
|
// 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.
|
2013-09-11 23:05:14 +00:00
|
|
|
//
|
|
|
|
|
|
|
|
#ifndef FAR_STENCILTABLES_H
|
|
|
|
#define FAR_STENCILTABLES_H
|
|
|
|
|
|
|
|
#include "../version.h"
|
|
|
|
|
2014-10-09 23:36:23 +00:00
|
|
|
#include "../far/types.h"
|
|
|
|
|
2014-09-05 22:07:46 +00:00
|
|
|
#include <cassert>
|
2013-09-11 23:05:14 +00:00
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
namespace OpenSubdiv {
|
|
|
|
namespace OPENSUBDIV_VERSION {
|
|
|
|
|
2014-09-05 22:07:46 +00:00
|
|
|
namespace Far {
|
2013-09-11 23:05:14 +00:00
|
|
|
|
2014-09-05 22:07:46 +00:00
|
|
|
/// \brief Vertex stencil descriptor
|
2013-09-11 23:05:14 +00:00
|
|
|
///
|
2014-09-05 22:07:46 +00:00
|
|
|
/// Allows access and manipulation of a single stencil in a StencilTables.
|
2013-09-11 23:05:14 +00:00
|
|
|
///
|
2014-09-05 22:07:46 +00:00
|
|
|
class Stencil {
|
|
|
|
|
2013-09-11 23:05:14 +00:00
|
|
|
public:
|
|
|
|
|
2014-09-05 22:07:46 +00:00
|
|
|
/// \brief Default constructor
|
|
|
|
Stencil() {}
|
|
|
|
|
|
|
|
/// \brief Constructor
|
|
|
|
///
|
|
|
|
/// @param size Table pointer to the size of the stencil
|
|
|
|
///
|
|
|
|
/// @param indices Table pointer to the vertex indices of the stencil
|
|
|
|
///
|
|
|
|
/// @param weights Table pointer to the vertex weights of the stencil
|
|
|
|
///
|
|
|
|
Stencil(unsigned char * size,
|
2014-10-09 23:36:23 +00:00
|
|
|
Index * indices,
|
|
|
|
float * weights)
|
2014-09-05 22:07:46 +00:00
|
|
|
: _size(size),
|
|
|
|
_indices(indices),
|
|
|
|
_weights(weights) {
|
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Copy constructor
|
|
|
|
Stencil(Stencil const & other) {
|
|
|
|
_size = other._size;
|
|
|
|
_indices = other._indices;
|
|
|
|
_weights = other._weights;
|
|
|
|
}
|
|
|
|
|
2014-09-19 00:48:34 +00:00
|
|
|
/// \brief Returns the size of the stencil
|
2013-09-11 23:05:14 +00:00
|
|
|
int GetSize() const {
|
|
|
|
return *_size;
|
|
|
|
}
|
|
|
|
|
2014-09-19 00:48:34 +00:00
|
|
|
/// \brief Returns the size of the stencil as a pointer
|
2014-09-12 23:59:16 +00:00
|
|
|
unsigned char * GetSizePtr() const {
|
|
|
|
return _size;
|
|
|
|
}
|
|
|
|
|
2013-12-20 19:01:58 +00:00
|
|
|
/// \brief Returns the control vertices indices
|
2014-10-09 23:36:23 +00:00
|
|
|
Index const * GetVertexIndices() const {
|
2013-09-11 23:05:14 +00:00
|
|
|
return _indices;
|
|
|
|
}
|
|
|
|
|
2013-12-20 19:01:58 +00:00
|
|
|
/// \brief Returns the interpolation weights
|
2014-09-05 22:07:46 +00:00
|
|
|
float const * GetWeights() const {
|
|
|
|
return _weights;
|
2013-09-11 23:05:14 +00:00
|
|
|
}
|
|
|
|
|
2014-09-05 22:07:46 +00:00
|
|
|
/// \brief Advance to the next stencil in the table
|
|
|
|
void Next() {
|
2013-09-11 23:05:14 +00:00
|
|
|
int stride = *_size;
|
|
|
|
++_size;
|
|
|
|
_indices += stride;
|
2014-09-05 22:07:46 +00:00
|
|
|
_weights += stride;
|
2013-09-11 23:05:14 +00:00
|
|
|
}
|
|
|
|
|
2014-09-05 22:07:46 +00:00
|
|
|
protected:
|
|
|
|
friend class StencilTablesFactory;
|
2014-09-12 23:59:16 +00:00
|
|
|
friend class LimitStencilTablesFactory;
|
2015-04-18 00:36:55 +00:00
|
|
|
friend class EndCapGregoryBasisPatchFactory;
|
|
|
|
friend class EndCapRegularPatchFactory;
|
2013-09-11 23:05:14 +00:00
|
|
|
|
2014-09-05 22:07:46 +00:00
|
|
|
unsigned char * _size;
|
2014-10-09 23:36:23 +00:00
|
|
|
Index * _indices;
|
2014-09-05 22:07:46 +00:00
|
|
|
float * _weights;
|
2013-09-11 23:05:14 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/// \brief Table of subdivision stencils.
|
|
|
|
///
|
|
|
|
/// Stencils are the most direct methods of evaluation of locations on the limit
|
|
|
|
/// of a surface. Every point of a limit surface can be computed by linearly
|
|
|
|
/// blending a collection of coarse control vertices.
|
|
|
|
///
|
|
|
|
/// A stencil assigns a series of control vertex indices with a blending weight
|
|
|
|
/// that corresponds to a unique parametric location of the limit surface. When
|
|
|
|
/// the control vertices move in space, the limit location can be very efficiently
|
|
|
|
/// recomputed simply by applying the blending weights to the series of coarse
|
|
|
|
/// control vertices.
|
|
|
|
///
|
2014-09-05 22:07:46 +00:00
|
|
|
class StencilTables {
|
2013-09-11 23:05:14 +00:00
|
|
|
|
|
|
|
public:
|
|
|
|
|
2014-09-05 22:07:46 +00:00
|
|
|
/// \brief Returns the number of stencils in the table
|
2013-09-11 23:05:14 +00:00
|
|
|
int GetNumStencils() const {
|
|
|
|
return (int)_sizes.size();
|
|
|
|
}
|
|
|
|
|
2014-09-19 00:48:34 +00:00
|
|
|
/// \brief Returns the number of control vertices indexed in the table
|
2014-09-05 22:07:46 +00:00
|
|
|
int GetNumControlVertices() const {
|
|
|
|
return _numControlVertices;
|
2013-09-11 23:05:14 +00:00
|
|
|
}
|
|
|
|
|
2014-09-05 22:07:46 +00:00
|
|
|
/// \brief Returns a Stencil at index i in the tables
|
2014-11-04 19:14:21 +00:00
|
|
|
Stencil GetStencil(Index i) const;
|
2013-09-11 23:05:14 +00:00
|
|
|
|
|
|
|
/// \brief Returns the number of control vertices of each stencil in the table
|
2014-09-05 22:07:46 +00:00
|
|
|
std::vector<unsigned char> const & GetSizes() const {
|
2013-09-11 23:05:14 +00:00
|
|
|
return _sizes;
|
|
|
|
}
|
|
|
|
|
2014-09-05 22:07:46 +00:00
|
|
|
/// \brief Returns the offset to a given stencil (factory may leave empty)
|
2014-10-09 23:36:23 +00:00
|
|
|
std::vector<Index> const & GetOffsets() const {
|
2013-09-11 23:05:14 +00:00
|
|
|
return _offsets;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Returns the indices of the control vertices
|
2014-10-09 23:36:23 +00:00
|
|
|
std::vector<Index> const & GetControlIndices() const {
|
2013-09-11 23:05:14 +00:00
|
|
|
return _indices;
|
|
|
|
}
|
|
|
|
|
2014-09-05 22:07:46 +00:00
|
|
|
/// \brief Returns the stencil interpolation weights
|
2013-09-11 23:05:14 +00:00
|
|
|
std::vector<float> const & GetWeights() const {
|
2014-09-05 22:07:46 +00:00
|
|
|
return _weights;
|
2013-09-11 23:05:14 +00:00
|
|
|
}
|
|
|
|
|
2014-09-19 00:48:34 +00:00
|
|
|
/// \brief Returns the stencil at index i in the tables
|
2014-11-04 19:14:21 +00:00
|
|
|
Stencil operator[] (Index index) const;
|
2014-09-19 00:48:34 +00:00
|
|
|
|
2014-09-05 22:07:46 +00:00
|
|
|
/// \brief Updates point values based on the control values
|
|
|
|
///
|
2014-11-04 19:14:21 +00:00
|
|
|
/// \note The destination buffers are assumed to have allocated at least
|
|
|
|
/// \c GetNumStencils() elements.
|
2014-09-05 22:07:46 +00:00
|
|
|
///
|
|
|
|
/// @param controlValues Buffer with primvar data for the control vertices
|
|
|
|
///
|
|
|
|
/// @param values Destination buffer for the interpolated primvar
|
|
|
|
/// data
|
|
|
|
///
|
|
|
|
/// @param start (skip to )index of first value to update
|
|
|
|
///
|
|
|
|
/// @param end Index of last value to update
|
2014-09-12 23:59:16 +00:00
|
|
|
///
|
2014-09-05 22:07:46 +00:00
|
|
|
template <class T>
|
2014-11-04 19:14:21 +00:00
|
|
|
void UpdateValues(T const *controlValues, T *values, Index start=-1, Index end=-1) const {
|
2014-09-05 22:07:46 +00:00
|
|
|
|
2014-10-29 17:53:17 +00:00
|
|
|
update(controlValues, values, _weights, start, end);
|
2013-09-11 23:05:14 +00:00
|
|
|
}
|
|
|
|
|
2014-09-12 23:59:16 +00:00
|
|
|
/// \brief Clears the stencils from the table
|
|
|
|
void Clear() {
|
|
|
|
_numControlVertices=0;
|
|
|
|
_sizes.clear();
|
|
|
|
_offsets.clear();
|
|
|
|
_indices.clear();
|
|
|
|
_weights.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
2014-09-05 22:07:46 +00:00
|
|
|
|
2015-02-05 06:33:32 +00:00
|
|
|
// Update values by applying cached stencil weights to new control values
|
2014-10-29 17:53:17 +00:00
|
|
|
template <class T> void update( T const *controlValues, T *values,
|
2014-11-04 19:14:21 +00:00
|
|
|
std::vector<float> const & valueWeights, Index start, Index end) const;
|
2014-09-05 22:07:46 +00:00
|
|
|
|
2014-10-29 17:53:17 +00:00
|
|
|
// Populate the offsets table from the stencil sizes in _sizes (factory helper)
|
|
|
|
void generateOffsets();
|
|
|
|
|
|
|
|
// Resize the table arrays (factory helper)
|
|
|
|
void resize(int nstencils, int nelems);
|
|
|
|
|
2014-09-12 23:59:16 +00:00
|
|
|
protected:
|
2015-04-09 20:58:47 +00:00
|
|
|
StencilTables() : _numControlVertices(0) {}
|
2014-09-05 22:07:46 +00:00
|
|
|
|
|
|
|
friend class StencilTablesFactory;
|
2015-04-18 00:36:55 +00:00
|
|
|
friend class EndCapGregoryBasisPatchFactory;
|
|
|
|
friend class EndCapRegularPatchFactory;
|
2014-09-05 22:07:46 +00:00
|
|
|
|
|
|
|
int _numControlVertices; // number of control vertices
|
|
|
|
|
|
|
|
std::vector<unsigned char> _sizes; // number of coeffiecient for each stencil
|
2014-10-09 23:36:23 +00:00
|
|
|
std::vector<Index> _offsets, // offset to the start of each stencil
|
2014-09-05 22:07:46 +00:00
|
|
|
_indices; // indices of contributing coarse vertices
|
|
|
|
std::vector<float> _weights; // stencil weight coefficients
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/// \brief Limit point stencil descriptor
|
|
|
|
///
|
|
|
|
class LimitStencil : public Stencil {
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
/// \brief Constructor
|
|
|
|
///
|
|
|
|
/// @param size Table pointer to the size of the stencil
|
|
|
|
///
|
|
|
|
/// @param indices Table pointer to the vertex indices of the stencil
|
|
|
|
///
|
|
|
|
/// @param weights Table pointer to the vertex weights of the stencil
|
|
|
|
///
|
|
|
|
/// @param duWeights Table pointer to the 'u' derivative weights
|
|
|
|
///
|
|
|
|
/// @param dvWeights Table pointer to the 'v' derivative weights
|
|
|
|
///
|
|
|
|
LimitStencil( unsigned char * size,
|
2014-10-09 23:36:23 +00:00
|
|
|
Index * indices,
|
|
|
|
float * weights,
|
|
|
|
float * duWeights,
|
|
|
|
float * dvWeights )
|
2014-09-05 22:07:46 +00:00
|
|
|
: Stencil(size, indices, weights),
|
|
|
|
_duWeights(duWeights),
|
|
|
|
_dvWeights(dvWeights) {
|
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief
|
|
|
|
float const * GetDuWeights() const {
|
|
|
|
return _duWeights;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief
|
|
|
|
float const * GetDvWeights() const {
|
|
|
|
return _dvWeights;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Advance to the next stencil in the table
|
|
|
|
void Next() {
|
|
|
|
int stride = *_size;
|
|
|
|
++_size;
|
|
|
|
_indices += stride;
|
|
|
|
_weights += stride;
|
|
|
|
_duWeights += stride;
|
|
|
|
_dvWeights += stride;
|
2013-09-11 23:05:14 +00:00
|
|
|
}
|
2014-09-05 22:07:46 +00:00
|
|
|
|
2013-09-11 23:05:14 +00:00
|
|
|
private:
|
2014-09-12 23:59:16 +00:00
|
|
|
|
|
|
|
friend class StencilTablesFactory;
|
|
|
|
friend class LimitStencilTablesFactory;
|
|
|
|
|
2014-09-05 22:07:46 +00:00
|
|
|
float * _duWeights, // pointer to stencil u derivative limit weights
|
|
|
|
* _dvWeights; // pointer to stencil v derivative limit weights
|
|
|
|
};
|
2013-09-11 23:05:14 +00:00
|
|
|
|
2014-09-05 22:07:46 +00:00
|
|
|
/// \brief Table of limit subdivision stencils.
|
|
|
|
///
|
|
|
|
///
|
|
|
|
class LimitStencilTables : public StencilTables {
|
2013-09-11 23:05:14 +00:00
|
|
|
|
2014-09-05 22:07:46 +00:00
|
|
|
public:
|
|
|
|
|
|
|
|
/// \brief Returns the 'u' derivative stencil interpolation weights
|
|
|
|
std::vector<float> const & GetDuWeights() const {
|
|
|
|
return _duWeights;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Returns the 'v' derivative stencil interpolation weights
|
|
|
|
std::vector<float> const & GetDvWeights() const {
|
|
|
|
return _dvWeights;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Updates derivative values based on the control values
|
|
|
|
///
|
|
|
|
/// \note The destination buffers ('uderivs' & 'vderivs') are assumed to
|
|
|
|
/// have allocated at least \c GetNumStencils() elements.
|
|
|
|
///
|
|
|
|
/// @param controlValues Buffer with primvar data for the control vertices
|
|
|
|
///
|
|
|
|
/// @param uderivs Destination buffer for the interpolated 'u'
|
|
|
|
/// derivative primvar data
|
|
|
|
///
|
|
|
|
/// @param vderivs Destination buffer for the interpolated 'v'
|
|
|
|
/// derivative primvar data
|
|
|
|
///
|
|
|
|
/// @param start (skip to )index of first value to update
|
|
|
|
///
|
|
|
|
/// @param end Index of last value to update
|
|
|
|
///
|
|
|
|
template <class T>
|
|
|
|
void UpdateDerivs(T const *controlValues, T *uderivs, T *vderivs,
|
|
|
|
int start=-1, int end=-1) const {
|
2013-09-11 23:05:14 +00:00
|
|
|
|
2014-10-29 17:53:17 +00:00
|
|
|
update(controlValues, uderivs, _duWeights, start, end);
|
|
|
|
update(controlValues, vderivs, _dvWeights, start, end);
|
2014-09-05 22:07:46 +00:00
|
|
|
}
|
2013-09-11 23:05:14 +00:00
|
|
|
|
2014-09-12 23:59:16 +00:00
|
|
|
/// \brief Clears the stencils from the table
|
|
|
|
void Clear() {
|
|
|
|
StencilTables::Clear();
|
|
|
|
_duWeights.clear();
|
|
|
|
_dvWeights.clear();
|
|
|
|
}
|
2013-09-11 23:05:14 +00:00
|
|
|
|
2014-09-05 22:07:46 +00:00
|
|
|
private:
|
2014-09-12 23:59:16 +00:00
|
|
|
friend class LimitStencilTablesFactory;
|
|
|
|
|
2014-10-29 17:53:17 +00:00
|
|
|
// Resize the table arrays (factory helper)
|
|
|
|
void resize(int nstencils, int nelems);
|
|
|
|
|
|
|
|
private:
|
2014-09-05 22:07:46 +00:00
|
|
|
std::vector<float> _duWeights, // u derivative limit stencil weights
|
|
|
|
_dvWeights; // v derivative limit stencil weights
|
2013-09-11 23:05:14 +00:00
|
|
|
};
|
|
|
|
|
2014-09-05 22:07:46 +00:00
|
|
|
|
|
|
|
// Update values by appling cached stencil weights to new control values
|
2013-09-11 23:05:14 +00:00
|
|
|
template <class T> void
|
2014-10-29 17:53:17 +00:00
|
|
|
StencilTables::update(T const *controlValues, T *values,
|
2014-11-04 19:14:21 +00:00
|
|
|
std::vector<float> const &valueWeights, Index start, Index end) const {
|
2014-09-05 22:07:46 +00:00
|
|
|
|
2014-10-29 22:52:07 +00:00
|
|
|
unsigned char const * sizes = &_sizes.at(0);
|
2014-10-09 23:36:23 +00:00
|
|
|
Index const * indices = &_indices.at(0);
|
2014-09-05 22:07:46 +00:00
|
|
|
float const * weights = &valueWeights.at(0);
|
2013-09-11 23:05:14 +00:00
|
|
|
|
2014-09-05 22:07:46 +00:00
|
|
|
if (start>0) {
|
2014-10-09 23:36:23 +00:00
|
|
|
assert(start<(Index)_offsets.size());
|
2014-10-29 22:52:07 +00:00
|
|
|
sizes += start;
|
2014-09-05 22:07:46 +00:00
|
|
|
indices += _offsets[start];
|
|
|
|
weights += _offsets[start];
|
|
|
|
values += start;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (end<start or end<0) {
|
|
|
|
end = GetNumStencils();
|
|
|
|
}
|
2013-09-11 23:05:14 +00:00
|
|
|
|
2014-09-05 22:07:46 +00:00
|
|
|
int nstencils = end - std::max(0, start);
|
2014-10-29 22:52:07 +00:00
|
|
|
for (int i=0; i<nstencils; ++i, ++sizes) {
|
2013-09-11 23:05:14 +00:00
|
|
|
|
|
|
|
// Zero out the result accumulators
|
|
|
|
values[i].Clear();
|
|
|
|
|
|
|
|
// For each element in the array, add the coefs contribution
|
2014-10-29 22:52:07 +00:00
|
|
|
for (int j=0; j<*sizes; ++j, ++indices, ++weights) {
|
2014-09-05 22:07:46 +00:00
|
|
|
values[i].AddWithWeight( controlValues[*indices], *weights );
|
2013-09-11 23:05:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-10-29 17:53:17 +00:00
|
|
|
inline void
|
|
|
|
StencilTables::generateOffsets() {
|
|
|
|
Index offset=0;
|
|
|
|
int noffsets = (int)_sizes.size();
|
|
|
|
_offsets.resize(noffsets);
|
|
|
|
for (int i=0; i<(int)_sizes.size(); ++i ) {
|
|
|
|
_offsets[i]=offset;
|
|
|
|
offset+=_sizes[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void
|
|
|
|
StencilTables::resize(int nstencils, int nelems) {
|
|
|
|
|
|
|
|
_sizes.resize(nstencils);
|
|
|
|
_indices.resize(nelems);
|
|
|
|
_weights.resize(nelems);
|
|
|
|
}
|
|
|
|
|
2014-09-05 22:07:46 +00:00
|
|
|
// Returns a Stencil at index i in the table
|
|
|
|
inline Stencil
|
2014-11-04 19:14:21 +00:00
|
|
|
StencilTables::GetStencil(Index i) const {
|
2013-09-11 23:05:14 +00:00
|
|
|
|
2014-09-19 00:48:34 +00:00
|
|
|
assert((not _offsets.empty()) and i<(int)_offsets.size());
|
|
|
|
|
2014-10-09 23:36:23 +00:00
|
|
|
Index ofs = _offsets[i];
|
2013-09-11 23:05:14 +00:00
|
|
|
|
2014-09-05 22:07:46 +00:00
|
|
|
return Stencil( const_cast<unsigned char *>(&_sizes[i]),
|
2014-10-09 23:36:23 +00:00
|
|
|
const_cast<Index *>(&_indices[ofs]),
|
|
|
|
const_cast<float *>(&_weights[ofs]) );
|
2013-09-11 23:05:14 +00:00
|
|
|
}
|
|
|
|
|
2014-09-24 21:06:18 +00:00
|
|
|
inline Stencil
|
2014-11-04 19:14:21 +00:00
|
|
|
StencilTables::operator[] (Index index) const {
|
2014-09-24 21:06:18 +00:00
|
|
|
return GetStencil(index);
|
|
|
|
}
|
|
|
|
|
2014-10-29 17:53:17 +00:00
|
|
|
inline void
|
|
|
|
LimitStencilTables::resize(int nstencils, int nelems) {
|
|
|
|
|
|
|
|
StencilTables::resize(nstencils, nelems);
|
|
|
|
_duWeights.resize(nelems);
|
|
|
|
_dvWeights.resize(nelems);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-09-05 22:07:46 +00:00
|
|
|
} // end namespace Far
|
2013-09-11 23:05:14 +00:00
|
|
|
|
|
|
|
} // end namespace OPENSUBDIV_VERSION
|
|
|
|
using namespace OPENSUBDIV_VERSION;
|
|
|
|
|
|
|
|
} // end namespace OpenSubdiv
|
|
|
|
|
|
|
|
#endif // FAR_STENCILTABLES_H
|