Files
Brandyn / Techy fcc1b09210 init
2026-04-04 15:40:51 -05:00

252 lines
8.6 KiB
C++

//
// Copyright 2021 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.
//
#ifndef OPENSUBDIV3_BFR_PATCH_TREE_H
#define OPENSUBDIV3_BFR_PATCH_TREE_H
#include "../version.h"
#include "../far/patchDescriptor.h"
#include "../far/patchParam.h"
#include "../vtr/array.h"
#include <vector>
#include <cstring>
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {
namespace Bfr {
//
// A PatchTree is a hierarchical collection of parametric patches that
// form a piecewise representation of the limit surface for a single face
// of a mesh. Using the patch representations from Far, it combines
// stripped down versions of the PatchTable and PatchMap from Far and a
// raw representation of stencils into a more compact representation
// suited to evaluating a single face. These are constructed based on
// adaptive refinement of a single face of a Far::TopologyRefiner.
//
// As the internal representation for the limit surface of a face with
// irregular topology, the PatchTree is not publicly exposed. As is the
// case with other internal Bfr classes whose headers are not exported,
// it is not further protected by the "internal" namespace.
//
// PatchTree was initially developed as an internal class for Far, so
// some comments may still reflect that origin.
//
// PatchTree also includes functionality beyond what is needed for Bfr
// for potential future use. Most notable is the ability for the tree
// to store a patch at interior nodes -- in addition to the leaf nodes.
// This allows the depth of evaluation to be varied, which takes place
// when searching a patch from the tree (specifying a maximum depth for
// the search). Construction options allow this functionality to be
// selectively enabled/disabled, and Bfr currently disables it.
//
class PatchTree {
public:
// Constructors are protected
~PatchTree();
// Simple public accessors:
int GetNumControlPoints() const { return _numControlPoints; }
int GetNumSubPatchPoints() const { return _numSubPatchPoints; }
int GetNumPointsTotal() const { return _numControlPoints +
_numSubPatchPoints; }
// These queries may not be necessary...
int GetDepth() const { return _treeDepth; }
int GetNumPatches() const { return (int)_patchParams.size(); }
// Methods to access stencils to compute patch points:
template <typename REAL>
REAL const * GetStencilMatrix() const;
bool UsesDoublePrecision() const { return _useDoublePrecision; }
// Methods supporting evaluation:
int HasSubFaces() const { return _numSubFaces > 0; }
int GetNumSubFaces() const { return _numSubFaces; }
int FindSubPatch(double u, double v, int subFace=0, int maxDep=-1) const;
typedef Vtr::ConstArray<int> PatchPointArray;
PatchPointArray GetSubPatchPoints(int subPatch) const;
Far::PatchParam GetSubPatchParam( int subPatch) const;
// Main evaluation methods - basis weights or limit stencils:
template <typename REAL>
int EvalSubPatchBasis(int subPatch, REAL u, REAL v, REAL w[],
REAL wDu[], REAL wDv[],
REAL wDuu[], REAL wDuv[], REAL wDvv[]) const;
template <typename REAL>
int EvalSubPatchStencils(int subPatch, REAL u, REAL v, REAL s[],
REAL sDu[], REAL sDv[],
REAL sDuu[], REAL sDuv[], REAL sDvv[]) const;
protected:
PatchTree();
friend class PatchTreeBuilder;
//
// Internal utilities to support the stencil matrix of variable precision
//
template <typename REAL> std::vector<REAL> const & getStencilMatrix() const;
template <typename REAL> std::vector<REAL> & getStencilMatrix();
template <typename REAL_MATRIX, typename REAL>
int evalSubPatchStencils(int subPatch, REAL u, REAL v, REAL s[],
REAL sDu[], REAL sDv[],
REAL sDuu[], REAL sDuv[], REAL sDvv[]) const;
protected:
// Internal quad-tree node type and assembly and search methods:
struct TreeNode {
struct Child {
unsigned int isSet : 1;
unsigned int isLeaf : 1;
unsigned int index : 28;
void SetIndex(int indexArg) { index = indexArg & 0xfffffff; }
};
TreeNode() : patchIndex(-1) {
std::memset(children, 0, sizeof(children));
}
void SetChildren(int index);
void SetChild(int quadrant, int index, bool isLeaf);
int patchIndex;
Child children[4];
};
int searchQuadtree(double u, double v, int subFace=0, int depth=-1) const;
void buildQuadtree();
TreeNode * assignLeafOrChildNode(TreeNode * node,
bool isLeaf, int quadrant, int index);
private:
// Private members:
typedef Far::PatchDescriptor::Type PatchType;
// Simple configuration members:
unsigned int _useDoublePrecision : 1;
unsigned int _patchesIncludeNonLeaf : 1;
unsigned int _patchesAreTriangular : 1;
PatchType _regPatchType;
PatchType _irregPatchType;
int _regPatchSize;
int _irregPatchSize;
int _patchPointStride;
// Simple topology inventory members:
int _numSubFaces;
int _numControlPoints;
int _numRefinedPoints;
int _numSubPatchPoints;
int _numIrregPatches;
// Vectors for points and PatchParams of all patches:
//
// Note we store both regular and irregular patch point indices in the
// same vector (using a common stride for each patch) and the patch type
// determined by the PatchParam -- in the same way that face-varying
// patches are stored in the PatchTable. Could also be stored in
// separate "patch arrays" or separated in other ways and managed with
// a bit more book-keeping.
//
std::vector<int> _patchPoints;
std::vector<Far::PatchParam> _patchParams;
// The quadtree organizing the patches:
std::vector<TreeNode> _treeNodes;
int _treeDepth;
// Array of stencils for computing patch points from control points
// (single or double to be used as specified on construction):
std::vector<float> _stencilMatrixFloat;
std::vector<double> _stencilMatrixDouble;
};
//
// Internal specializations to support the stencil matrix of variable
// precision -- const access presumes it is non-empty (and so assert)
// while non-const access may be used to populate it.
//
template <>
inline std::vector<float> const &
PatchTree::getStencilMatrix<float>() const {
assert(!_stencilMatrixFloat.empty());
return _stencilMatrixFloat;
}
template <>
inline std::vector<double> const &
PatchTree::getStencilMatrix<double>() const {
assert(!_stencilMatrixDouble.empty());
return _stencilMatrixDouble;
}
template <>
inline std::vector<float> &
PatchTree::getStencilMatrix<float>() {
return _stencilMatrixFloat;
}
template <>
inline std::vector<double> &
PatchTree::getStencilMatrix<double>() {
return _stencilMatrixDouble;
}
//
// Inline methods:
//
inline Far::PatchParam
PatchTree::GetSubPatchParam(int subPatch) const {
return _patchParams[subPatch];
}
inline int
PatchTree::FindSubPatch(double u, double v, int subFace, int maxDep) const {
return searchQuadtree(u, v, subFace, maxDep);
}
template <typename REAL>
inline REAL const *
PatchTree::GetStencilMatrix() const {
return &getStencilMatrix<REAL>()[0];
}
} // end namespace Bfr
} // end namespace OPENSUBDIV_VERSION
using namespace OPENSUBDIV_VERSION;
} // end namespace OpenSubdiv
#endif /* OPENSUBDIV3_BFR_PATCH_TREE */