mirror of
https://github.com/PixarAnimationStudios/OpenSubdiv
synced 2024-11-10 06:10:07 +00:00
Merge pull request #502 from barfowl/patch_eval
Refactor public patch evaluation methods exposed by Far::PatchTables
This commit is contained in:
commit
c82b3d551d
@ -446,7 +446,8 @@ createFVarPatches(OpenSubdiv::Far::TopologyRefiner const & refiner,
|
||||
for (int i=0; i<tessFactor; ++i) {
|
||||
for (int j=0; j<tessFactor; ++j, ++vert) {
|
||||
handle.patchIndex = patch;
|
||||
patchTables.EvaluateFaceVarying(channel, handle, uvs[i], uvs[j], fvarBuffer, *vert);
|
||||
// To be replaced with EvaluateBasis() for the appropriate channel:
|
||||
//patchTables.EvaluateFaceVarying(channel, handle, uvs[i], uvs[j], fvarBuffer, *vert);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ set(SOURCE_FILES
|
||||
endCapGregoryBasisPatchFactory.cpp
|
||||
endCapLegacyGregoryPatchFactory.cpp
|
||||
gregoryBasis.cpp
|
||||
interpolate.cpp
|
||||
patchBasis.cpp
|
||||
patchDescriptor.cpp
|
||||
patchMap.cpp
|
||||
patchTables.cpp
|
||||
@ -51,7 +51,7 @@ set(PUBLIC_HEADER_FILES
|
||||
endCapGregoryBasisPatchFactory.h
|
||||
endCapLegacyGregoryPatchFactory.h
|
||||
gregoryBasis.h
|
||||
interpolate.h
|
||||
patchBasis.h
|
||||
patchDescriptor.h
|
||||
patchParam.h
|
||||
patchMap.h
|
||||
|
@ -1,245 +0,0 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
#ifndef OPENSUBDIV3_FAR_INTERPOLATE_H
|
||||
#define OPENSUBDIV3_FAR_INTERPOLATE_H
|
||||
|
||||
#include "../version.h"
|
||||
|
||||
#include "../far/patchParam.h"
|
||||
#include "../far/stencilTables.h"
|
||||
|
||||
namespace OpenSubdiv {
|
||||
namespace OPENSUBDIV_VERSION {
|
||||
|
||||
namespace Far {
|
||||
|
||||
// XXXX
|
||||
//
|
||||
// Note 1 : interpolation functions will eventually need to be augmented to
|
||||
// handle second order derivatives
|
||||
//
|
||||
// Note 2 : evaluation of derivatives need to be ptional (passing NULL to
|
||||
// dQ1 and dQ2 to the weights functions will do this)
|
||||
|
||||
void GetBilinearWeights(PatchParam::BitField bits,
|
||||
float s, float t, float point[4], float deriv1[4], float deriv2[4]);
|
||||
|
||||
void GetBezierWeights(PatchParam::BitField bits,
|
||||
float s, float t, float point[16], float deriv1[16], float deriv2[16]);
|
||||
|
||||
void GetBSplineWeights(PatchParam::BitField bits,
|
||||
float s, float t, float point[16], float deriv1[16], float deriv2[16]);
|
||||
|
||||
void GetGregoryWeights(PatchParam::BitField bits,
|
||||
float s, float t, float point[20], float deriv1[20], float deriv2[20]);
|
||||
|
||||
|
||||
/// \brief Interpolate the (s,t) parametric location of a bilinear (quad)
|
||||
/// patch
|
||||
///
|
||||
/// @param cvs Array of 16 control vertex indices
|
||||
///
|
||||
/// @param Q Array of 16 bicubic weights for the control vertices
|
||||
///
|
||||
/// @param Qd1 Array of 16 bicubic 's' tangent weights for the control
|
||||
/// vertices
|
||||
///
|
||||
/// @param Qd2 Array of 16 bicubic 't' tangent weights for the control
|
||||
/// vertices
|
||||
///
|
||||
/// @param src Source primvar buffer (control vertices data)
|
||||
///
|
||||
/// @param dst Destination primvar buffer (limit surface data)
|
||||
///
|
||||
template <class T, class U>
|
||||
inline void
|
||||
InterpolateBilinearPatch(Index const * cvs,
|
||||
float const * Q, float const *Qd1, float const *Qd2,
|
||||
T const & src, U & dst) {
|
||||
|
||||
//
|
||||
// v0 -- v1
|
||||
// |.....|
|
||||
// |.....|
|
||||
// v3 -- v2
|
||||
//
|
||||
for (int k=0; k<4; ++k) {
|
||||
dst.AddWithWeight(src[cvs[k]], Q[k], Qd1[k], Qd2[k]);
|
||||
}
|
||||
}
|
||||
|
||||
/// \brief Interpolate the (s,t) parametric location of a regular bicubic
|
||||
/// patch
|
||||
///
|
||||
/// @param cvs Array of 16 control vertex indices
|
||||
///
|
||||
/// @param Q Array of 16 bicubic weights for the control vertices
|
||||
///
|
||||
/// @param Qd1 Array of 16 bicubic 's' tangent weights for the control
|
||||
/// vertices
|
||||
///
|
||||
/// @param Qd2 Array of 16 bicubic 't' tangent weights for the control
|
||||
/// vertices
|
||||
///
|
||||
/// @param src Source primvar buffer (control vertices data)
|
||||
///
|
||||
/// @param dst Destination primvar buffer (limit surface data)
|
||||
///
|
||||
template <class T, class U>
|
||||
inline void
|
||||
InterpolateRegularPatch(Index const * cvs,
|
||||
float const * Q, float const *Qd1, float const *Qd2,
|
||||
T const & src, U & dst) {
|
||||
|
||||
//
|
||||
// v0 -- v1 -- v2 -- v3
|
||||
// |.....|.....|.....|
|
||||
// |.....|.....|.....|
|
||||
// v4 -- v5 -- v6 -- v7
|
||||
// |.....|.....|.....|
|
||||
// |.....|.....|.....|
|
||||
// v8 -- v9 -- v10-- v11
|
||||
// |.....|.....|.....|
|
||||
// |.....|.....|.....|
|
||||
// v12-- v13-- v14-- v15
|
||||
//
|
||||
for (int k=0; k<16; ++k) {
|
||||
dst.AddWithWeight(src[cvs[k]], Q[k], Qd1[k], Qd2[k]);
|
||||
}
|
||||
}
|
||||
|
||||
/// \brief Interpolate the (s,t) parametric location of a Gregory bicubic
|
||||
/// patch
|
||||
///
|
||||
/// @param cvs Array of 20 control vertex indices
|
||||
///
|
||||
/// @param s Patch coordinate (in coarse face normalized space)
|
||||
///
|
||||
/// @param t Patch coordinate (in coarse face normalized space)
|
||||
///
|
||||
/// @param Q Array of 9 bicubic weights for the control vertices
|
||||
///
|
||||
/// @param Qd1 Array of 9 bicubic 's' tangent weights for the control
|
||||
/// vertices
|
||||
///
|
||||
/// @param Qd2 Array of 9 bicubic 't' tangent weights for the control
|
||||
/// vertices
|
||||
///
|
||||
/// @param src Source primvar buffer (control vertices data)
|
||||
///
|
||||
/// @param dst Destination primvar buffer (limit surface data)
|
||||
///
|
||||
template <class T, class U>
|
||||
inline void
|
||||
InterpolateGregoryPatch(Index const *cvs, float s, float t,
|
||||
float const * Q, float const *Qd1, float const *Qd2,
|
||||
T const & src, U & dst) {
|
||||
|
||||
float ss = 1-s,
|
||||
tt = 1-t;
|
||||
// remark #1572: floating-point equality and inequality comparisons are unreliable
|
||||
#ifdef __INTEL_COMPILER
|
||||
#pragma warning disable 1572
|
||||
#endif
|
||||
float d11 = s+t; if(s+t==0.0f) d11 = 1.0f;
|
||||
float d12 = ss+t; if(ss+t==0.0f) d12 = 1.0f;
|
||||
float d21 = s+tt; if(s+tt==0.0f) d21 = 1.0f;
|
||||
float d22 = ss+tt; if(ss+tt==0.0f) d22 = 1.0f;
|
||||
#ifdef __INTEL_COMPILER
|
||||
#pragma warning enable 1572
|
||||
#endif
|
||||
|
||||
float weights[4][2] = { { s/d11, t/d11 },
|
||||
{ ss/d12, t/d12 },
|
||||
{ s/d21, tt/d21 },
|
||||
{ ss/d22, tt/d22 } };
|
||||
|
||||
//
|
||||
// P3 e3- e2+ P2
|
||||
// 15------17-------11--------10
|
||||
// | | | |
|
||||
// | | | |
|
||||
// | | f3- | f2+ |
|
||||
// | 19 13 |
|
||||
// e3+ 16-----18 14-----12 e2-
|
||||
// | f3+ f2- |
|
||||
// | |
|
||||
// | |
|
||||
// | f0- f1+ |
|
||||
// e0- 2------4 8------6 e1+
|
||||
// | 3 9 |
|
||||
// | | f0+ | f1- |
|
||||
// | | | |
|
||||
// | | | |
|
||||
// O--------1--------7--------5
|
||||
// P0 e0+ e1- P1
|
||||
//
|
||||
|
||||
// gregory-to-bezier map
|
||||
static int const permute[16] =
|
||||
{ 0, 1, 7, 5, 2, -1, -2, 6, 16, -3, -4, 12, 15, 17, 11, 10 };
|
||||
|
||||
for (int k = 0; k < 16; ++k) {
|
||||
|
||||
int index = permute[k];
|
||||
if (index >=0) {
|
||||
dst.AddWithWeight(src[cvs[index]], Q[k], Qd1[k], Qd2[k]);
|
||||
} else if (index == -1) {
|
||||
// 3, 4
|
||||
float w0 = weights[0][0];
|
||||
float w1 = weights[0][1];
|
||||
dst.AddWithWeight(src[cvs[3]], w0*Q[k], w0*Qd1[k], w0*Qd2[k]);
|
||||
dst.AddWithWeight(src[cvs[4]], w1*Q[k], w1*Qd1[k], w1*Qd2[k]);
|
||||
} else if (index == -2) {
|
||||
// 8, 9
|
||||
float w0 = weights[1][0];
|
||||
float w1 = weights[1][1];
|
||||
dst.AddWithWeight(src[cvs[9]], w0*Q[k], w0*Qd1[k], w0*Qd2[k]);
|
||||
dst.AddWithWeight(src[cvs[8]], w1*Q[k], w1*Qd1[k], w1*Qd2[k]);
|
||||
} else if (index == -3) {
|
||||
// 18, 19
|
||||
float w0 = weights[2][0];
|
||||
float w1 = weights[2][1];
|
||||
dst.AddWithWeight(src[cvs[19]], w0*Q[k], w0*Qd1[k], w0*Qd2[k]);
|
||||
dst.AddWithWeight(src[cvs[18]], w1*Q[k], w1*Qd1[k], w1*Qd2[k]);
|
||||
} else if (index == -4) {
|
||||
// 13, 14
|
||||
float w0 = weights[3][0];
|
||||
float w1 = weights[3][1];
|
||||
dst.AddWithWeight(src[cvs[13]], w0*Q[k], w0*Qd1[k], w0*Qd2[k]);
|
||||
dst.AddWithWeight(src[cvs[14]], w1*Q[k], w1*Qd1[k], w1*Qd2[k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // end namespace Far
|
||||
|
||||
} // end namespace OPENSUBDIV_VERSION
|
||||
using namespace OPENSUBDIV_VERSION;
|
||||
|
||||
} // end namespace OpenSubdiv
|
||||
|
||||
#endif /* OPENSUBDIV3_FAR_INTERPOLATE_H */
|
@ -22,7 +22,7 @@
|
||||
// language governing permissions and limitations under the Apache License.
|
||||
//
|
||||
|
||||
#include "../far/interpolate.h"
|
||||
#include "../far/patchBasis.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
@ -31,6 +31,7 @@ namespace OpenSubdiv {
|
||||
namespace OPENSUBDIV_VERSION {
|
||||
|
||||
namespace Far {
|
||||
namespace internal {
|
||||
|
||||
enum SplineBasis {
|
||||
BASIS_BILINEAR,
|
||||
@ -424,6 +425,7 @@ void GetGregoryWeights(PatchParam::BitField bits,
|
||||
}
|
||||
}
|
||||
|
||||
} // end namespace internal
|
||||
} // end namespace Far
|
||||
|
||||
} // end namespace OPENSUBDIV_VERSION
|
69
opensubdiv/far/patchBasis.h
Normal file
69
opensubdiv/far/patchBasis.h
Normal file
@ -0,0 +1,69 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
#ifndef OPENSUBDIV3_FAR_PATCH_BASIS_H
|
||||
#define OPENSUBDIV3_FAR_PATCH_BASIS_H
|
||||
|
||||
#include "../version.h"
|
||||
|
||||
#include "../far/patchParam.h"
|
||||
|
||||
namespace OpenSubdiv {
|
||||
namespace OPENSUBDIV_VERSION {
|
||||
|
||||
namespace Far {
|
||||
namespace internal {
|
||||
|
||||
//
|
||||
// XXXX barfowl: These functions are being kept in place while more complete
|
||||
// underlying support for all patch types is being worked out. That support
|
||||
// will include a larger set of patch types (eventually including triangular
|
||||
// patches for Loop) and arbitrary differentiation of all (to support second
|
||||
// derivatives and other needs).
|
||||
//
|
||||
// So this interface will be changing in future.
|
||||
//
|
||||
|
||||
void GetBilinearWeights(PatchParam::BitField bits,
|
||||
float s, float t, float wP[4], float wDs[4], float wDt[4]);
|
||||
|
||||
void GetBezierWeights(PatchParam::BitField bits,
|
||||
float s, float t, float wP[16], float wDs[16], float wDt[16]);
|
||||
|
||||
void GetBSplineWeights(PatchParam::BitField bits,
|
||||
float s, float t, float wP[16], float wDs[16], float wDt[16]);
|
||||
|
||||
void GetGregoryWeights(PatchParam::BitField bits,
|
||||
float s, float t, float wP[20], float wDs[20], float wDt[20]);
|
||||
|
||||
|
||||
} // end namespace internal
|
||||
} // end namespace Far
|
||||
|
||||
} // end namespace OPENSUBDIV_VERSION
|
||||
using namespace OPENSUBDIV_VERSION;
|
||||
|
||||
} // end namespace OpenSubdiv
|
||||
|
||||
#endif /* OPENSUBDIV3_FAR_PATCH_BASIS_H */
|
@ -23,6 +23,7 @@
|
||||
//
|
||||
|
||||
#include "../far/patchTables.h"
|
||||
#include "../far/patchBasis.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
@ -507,6 +508,27 @@ PatchTables::print() const {
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Evaluate basis functions for position and first derivatives at (s,t):
|
||||
//
|
||||
void
|
||||
PatchTables::EvaluateBasis(PatchHandle const & handle, float s, float t,
|
||||
float wP[], float wDs[], float wDt[]) const {
|
||||
|
||||
PatchDescriptor::Type patchType = GetPatchArrayDescriptor(handle.arrayIndex).GetType();
|
||||
PatchParam::BitField const & patchBits = _paramTable[handle.patchIndex].bitField;
|
||||
|
||||
if (patchType == PatchDescriptor::REGULAR) {
|
||||
internal::GetBSplineWeights(patchBits, s, t, wP, wDs, wDt);
|
||||
} else if (patchType == PatchDescriptor::GREGORY_BASIS) {
|
||||
internal::GetGregoryWeights(patchBits, s, t, wP, wDs, wDt);
|
||||
} else if (patchType == PatchDescriptor::QUADS) {
|
||||
internal::GetBilinearWeights(patchBits, s, t, wP, wDs, wDt);
|
||||
} else {
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
} // end namespace Far
|
||||
|
||||
} // end namespace OPENSUBDIV_VERSION
|
||||
|
@ -27,8 +27,9 @@
|
||||
|
||||
#include "../version.h"
|
||||
|
||||
#include "../far/interpolate.h"
|
||||
#include "../far/patchDescriptor.h"
|
||||
#include "../far/patchParam.h"
|
||||
#include "../far/stencilTables.h"
|
||||
|
||||
#include "../sdc/options.h"
|
||||
|
||||
@ -277,13 +278,11 @@ public:
|
||||
public:
|
||||
|
||||
//@{
|
||||
/// @name Interpolation methods
|
||||
//
|
||||
|
||||
/// \brief Interpolate the (s,t) parametric location of a *bilinear* patch
|
||||
/// @name Evaluation methods
|
||||
///
|
||||
/// \note This method can only be used on uniform PatchTables of quads (see
|
||||
/// IsFeatureAdaptive() method)
|
||||
|
||||
/// \brief Evaluate basis functions for position and first derivatives at a
|
||||
/// given (s,t) parametric location of a patch.
|
||||
///
|
||||
/// @param handle A patch handle indentifying the sub-patch containing the
|
||||
/// (s,t) location
|
||||
@ -292,51 +291,14 @@ public:
|
||||
///
|
||||
/// @param t Patch coordinate (in coarse face normalized space)
|
||||
///
|
||||
/// @param src Source primvar buffer (control vertices data)
|
||||
/// @param wP Weights (evaluated basis functions) for the position
|
||||
///
|
||||
/// @param dst Destination primvar buffer (limit surface data)
|
||||
/// @param wDs Weights (evaluated basis functions) for derivative wrt s
|
||||
///
|
||||
template <class T, class U> void EvaluateBilinear(PatchHandle const & handle,
|
||||
float s, float t, T const & src, U & dst) const;
|
||||
|
||||
|
||||
/// \brief Interpolate the (s,t) parametric location of a *bicubic* patch
|
||||
/// @param wDt Weights (evaluated basis functions) for derivative wrt t
|
||||
///
|
||||
/// \note This method can only be used on feature adaptive PatchTables (ie.
|
||||
/// IsFeatureAdaptive() is false)
|
||||
///
|
||||
/// @param handle A patch handle indentifying the sub-patch containing the
|
||||
/// (s,t) location
|
||||
///
|
||||
/// @param s Patch coordinate (in coarse face normalized space)
|
||||
///
|
||||
/// @param t Patch coordinate (in coarse face normalized space)
|
||||
///
|
||||
/// @param src Source primvar buffer (control vertices data)
|
||||
///
|
||||
/// @param dst Destination primvar buffer (limit surface data)
|
||||
///
|
||||
template <class T, class U> void Evaluate(PatchHandle const & handle,
|
||||
float s, float t, T const & src, U & dst) const;
|
||||
|
||||
/// \brief Interpolate the (s,t) parametric location of a *bicubic*
|
||||
/// face-varying patch
|
||||
///
|
||||
/// @param channel The face-varying primvar channel
|
||||
///
|
||||
/// @param handle A patch handle indentifying the sub-patch containing the
|
||||
/// (s,t) location
|
||||
///
|
||||
/// @param s Patch coordinate (in coarse face normalized space)
|
||||
///
|
||||
/// @param t Patch coordinate (in coarse face normalized space)
|
||||
///
|
||||
/// @param src Source primvar buffer (control vertices data)
|
||||
///
|
||||
/// @param dst Destination primvar buffer (limit surface data)
|
||||
///
|
||||
template <class T, class U> void EvaluateFaceVarying(int channel,
|
||||
PatchHandle const & handle, float s, float t, T const & src, U & dst) const;
|
||||
void EvaluateBasis(PatchHandle const & handle, float s, float t,
|
||||
float wP[], float wDs[], float wDt[]) const;
|
||||
|
||||
//@}
|
||||
|
||||
@ -442,117 +404,6 @@ private:
|
||||
std::vector<float> _sharpnessValues; // Sharpness values.
|
||||
};
|
||||
|
||||
// XXXX manuelk evaluation should have the following interface :
|
||||
// - EvaluateVertex<>()
|
||||
// - EvaluateVarying<>()
|
||||
// - EvaluateFaceVarying<>()
|
||||
// this refactor is pending the move of fvar channels as a private data
|
||||
// structure inside PatchTables, along with the addition of accessors that
|
||||
// use PatchHandle and work that hides the indexing of the patches inside
|
||||
// the tables
|
||||
|
||||
// Interpolates primvar limit at the given parametric location on a patch
|
||||
template <class T, class U>
|
||||
inline void
|
||||
PatchTables::Evaluate(PatchHandle const & handle, float s, float t,
|
||||
T const & src, U & dst) const {
|
||||
|
||||
assert(IsFeatureAdaptive());
|
||||
|
||||
PatchParam::BitField const & bits = _paramTable[handle.patchIndex].bitField;
|
||||
|
||||
PatchDescriptor::Type ptype =
|
||||
GetPatchArrayDescriptor(handle.arrayIndex).GetType();
|
||||
|
||||
dst.Clear();
|
||||
|
||||
float Q[16], Qd1[16], Qd2[16];
|
||||
|
||||
if (ptype==PatchDescriptor::REGULAR) {
|
||||
|
||||
ConstIndexArray cvs = GetPatchVertices(handle);
|
||||
|
||||
GetBSplineWeights(bits, s, t, Q, Qd1, Qd2);
|
||||
InterpolateRegularPatch(cvs.begin(), Q, Qd1, Qd2, src, dst);
|
||||
|
||||
} else if (ptype==PatchDescriptor::GREGORY_BASIS) {
|
||||
|
||||
ConstIndexArray cvs = GetPatchVertices(handle);
|
||||
|
||||
GetBezierWeights(bits, s, t, Q, Qd1, Qd2);
|
||||
InterpolateGregoryPatch(cvs.begin(), s, t, Q, Qd1, Qd2, src, dst);
|
||||
|
||||
} else if (ptype==PatchDescriptor::QUADS) {
|
||||
|
||||
ConstIndexArray cvs = GetPatchVertices(handle);
|
||||
|
||||
GetBilinearWeights(bits, s, t, Q, Qd1, Qd2);
|
||||
InterpolateBilinearPatch(cvs.begin(), Q, Qd1, Qd2, src, dst);
|
||||
|
||||
} else {
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
// Interpolates the limit position of a parametric location on a face-varying
|
||||
// patch
|
||||
// XXXX manuelk this method is very similar to the vertex Evaluate<>() method
|
||||
// -> we should eventually merge them
|
||||
template <class T, class U>
|
||||
inline void
|
||||
PatchTables::EvaluateFaceVarying(int channel, PatchHandle const & handle,
|
||||
float s, float t, T const & src, U & dst) const {
|
||||
|
||||
ConstIndexArray cvs = GetFVarPatchValues(channel, handle);
|
||||
|
||||
PatchDescriptor::Type type = GetFVarPatchType(channel, handle);
|
||||
|
||||
PatchParam::BitField bits;
|
||||
bits.Clear();
|
||||
|
||||
float Q[16], Qd1[16], Qd2[16];
|
||||
|
||||
switch (type) {
|
||||
case PatchDescriptor::QUADS:
|
||||
GetBilinearWeights(bits, s, t, Q, Qd1, Qd2);
|
||||
InterpolateBilinearPatch(cvs.begin(), Q, Qd1, Qd2, src, dst);
|
||||
break;
|
||||
case PatchDescriptor::TRIANGLES:
|
||||
assert("not implemented yet");
|
||||
case PatchDescriptor::REGULAR:
|
||||
GetBSplineWeights(bits, s, t, Q, Qd1, Qd2);
|
||||
InterpolateRegularPatch(cvs.begin(), Q, Qd1, Qd2, src, dst);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
|
||||
// XXXX manuelk - how do we handle end-patches ?
|
||||
// - is there a bicubic patch that we could use to reduce
|
||||
// isolation of bilinear boundaries with smooth a interior ?
|
||||
}
|
||||
}
|
||||
|
||||
// Interpolates primvar at the given parametric location on a bilinear patch
|
||||
template <class T, class U>
|
||||
inline void
|
||||
PatchTables::EvaluateBilinear(PatchHandle const & handle, float s, float t,
|
||||
T const & src, U & dst) const {
|
||||
|
||||
ConstIndexArray cvs = GetPatchVertices(handle);
|
||||
assert(cvs.size()==4);
|
||||
|
||||
PatchParam::BitField const & bits =
|
||||
_paramTable[handle.patchIndex].bitField;
|
||||
|
||||
dst.Clear();
|
||||
|
||||
float Q[4], Qd1[4], Qd2[4];
|
||||
GetBilinearWeights(bits, s, t, Q, Qd1, Qd2);
|
||||
|
||||
InterpolateBilinearPatch(cvs.begin(), Q, Qd1, Qd2, src, dst);
|
||||
}
|
||||
|
||||
|
||||
} // end namespace Far
|
||||
|
||||
} // end namespace OPENSUBDIV_VERSION
|
||||
|
@ -495,6 +495,8 @@ LimitStencilTablesFactory::Create(TopologyRefiner const & refiner,
|
||||
|
||||
// XXXX (manuelk) we can make uniform (bilinear) stencils faster with a
|
||||
// dedicated code path that does not use PatchTables or the PatchMap
|
||||
float wP[20], wDs[20], wDt[20];
|
||||
|
||||
for (int i=0, currentStencil=0; i<(int)locationArrays.size(); ++i) {
|
||||
|
||||
LocationArray const & array = locationArrays[i];
|
||||
@ -506,16 +508,22 @@ LimitStencilTablesFactory::Create(TopologyRefiner const & refiner,
|
||||
float s = array.s[j],
|
||||
t = array.t[j];
|
||||
|
||||
PatchMap::Handle const * handle =
|
||||
patchmap.FindPatch(array.ptexIdx, s, t);
|
||||
PatchMap::Handle const * handle = patchmap.FindPatch(array.ptexIdx, s, t);
|
||||
|
||||
if (handle) {
|
||||
|
||||
ConstIndexArray cvs = patchTables->GetPatchVertices(*handle);
|
||||
|
||||
patchTables->EvaluateBasis(*handle, s, t, wP, wDs, wDt);
|
||||
|
||||
StencilTables const & src = *cvstencils;
|
||||
ProtoLimitStencil dst = alloc[currentStencil];
|
||||
if (uniform) {
|
||||
patchtables->EvaluateBilinear(*handle, s, t, *cvstencils, dst);
|
||||
} else {
|
||||
patchtables->Evaluate(*handle, s, t, *cvstencils, dst);
|
||||
|
||||
dst.Clear();
|
||||
for (int k = 0; k < cvs.size(); ++k) {
|
||||
dst.AddWithWeight(src[cvs[k]], wP[k], wDs[k], wDt[k]);
|
||||
}
|
||||
|
||||
++numLimitStencils;
|
||||
}
|
||||
}
|
||||
|
@ -130,11 +130,20 @@ CpuEvaluator::EvalPatches(const float *src,
|
||||
BufferAdapter<const float> srcT(src, srcDesc.length, srcDesc.stride);
|
||||
BufferAdapter<float> dstT(dst, dstDesc.length, dstDesc.stride);
|
||||
|
||||
float wP[20], wDs[20], wDt[20];
|
||||
|
||||
for (size_t i = 0; i < patchCoords.size(); ++i) {
|
||||
PatchCoord const &coords = patchCoords[i];
|
||||
|
||||
patchTable->Evaluate(coords.handle, coords.s, coords.t,
|
||||
srcT, dstT);
|
||||
patchTable->EvaluateBasis(coords.handle, coords.s, coords.t, wP, wDs, wDt);
|
||||
|
||||
Far::ConstIndexArray cvs = patchTable->GetPatchVertices(coords.handle);
|
||||
|
||||
dstT.Clear();
|
||||
for (int j = 0; j < cvs.size(); ++j) {
|
||||
dstT.AddWithWeight(srcT[cvs[j]], wP[j], wDs[j], wDt[j]);
|
||||
}
|
||||
|
||||
++count;
|
||||
++dstT;
|
||||
}
|
||||
|
@ -33,7 +33,7 @@
|
||||
// adaptive isolation of topological features. This process converts the
|
||||
// input polygonal control cage into a collection of bi-cubic patches.
|
||||
//
|
||||
// We can then evaluate the patches are random parametric locations and
|
||||
// We can then evaluate the patches at random parametric locations and
|
||||
// obtain analytical positions and tangents on the limit surface.
|
||||
//
|
||||
// The results are dumped into a MEL script that draws 'streak' particle
|
||||
@ -102,7 +102,8 @@ struct Vertex {
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Limit frame container implementation.
|
||||
// Limit frame container implementation -- this interface is not strictly
|
||||
// required but follows a similar pattern to Vertex.
|
||||
//
|
||||
struct LimitFrame {
|
||||
|
||||
@ -174,6 +175,8 @@ int main(int, char **) {
|
||||
|
||||
srand( static_cast<int>(2147483647) );
|
||||
|
||||
float pWeights[20], dsWeights[20], dtWeights[20];
|
||||
|
||||
for (int face=0, count=0; face<nfaces; ++face) {
|
||||
|
||||
for (int sample=0; sample<nsamples; ++sample, ++count) {
|
||||
@ -186,8 +189,17 @@ int main(int, char **) {
|
||||
patchmap.FindPatch(face, s, t);
|
||||
assert(handle);
|
||||
|
||||
// Evaluate the limit frame
|
||||
patchTables->Evaluate(*handle, s, t, &verts[0], samples[count]);
|
||||
// Evaluate the patch weights, identify the CVs and compute the limit frame:
|
||||
patchTables->EvaluateBasis(*handle, s, t, pWeights, dsWeights, dtWeights);
|
||||
|
||||
Far::ConstIndexArray cvs = patchTables->GetPatchVertices(*handle);
|
||||
|
||||
LimitFrame & dst = samples[count];
|
||||
dst.Clear();
|
||||
for (int cv=0; cv < cvs.size(); ++cv) {
|
||||
dst.AddWithWeight(verts[cvs[cv]], pWeights[cv], dsWeights[cv], dtWeights[cv]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user