// // 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 "../osd/cpuEvalLimitKernel.h" #include "../far/interpolate.h" #include "../far/stencilTables.h" #include #include #include #include #include #include #include namespace OpenSubdiv { namespace OPENSUBDIV_VERSION { namespace Osd { #ifdef TENSOR_PRODUCT_CUBIC_SPLINES // manuelk code was refactored to use the matrix formulation of cubic splines // exposed in Far::PatchTables for consistency. I am keeping these temporarily // for reference. inline void cubicBezier(float u, float B[4], float BU[3]) { float u2 = u*u, w0 = 1.0f - u, w2 = w0 * w0; B[0] = w0*w2; B[1] = 3.0f * u * w2; B[2] = 3.0f * u2 * w0; B[3] = u*u2; if (BU) { BU[0] = w2; BU[1] = 2.0f * u * w0; BU[2] = u2; } } inline void cubicBSpline(float u, float B[4], float BU[4]) { float t = u; float s = 1.0f - u; float A0 = s * (0.5f * s); float A1 = t * (s + 0.5f * t) + s * (0.5f * s + t); float A2 = t * ( 0.5f * t); B[0] = 1.f/3.f * s * A0; B[1] = (2.f/3.f * s + t) * A0 + (2.f/3.f * s + 1.f/3.f * t) * A1; B[2] = (1.f/3.f * s + 2.f/3.f * t) * A1 + ( s + 2.f/3.f * t) * A2; B[3] = 1.f/3.f * t * A2; if (BU) { BU[0] = - A0; BU[1] = A0 - A1; BU[2] = A1 - A2; BU[3] = A2; } } inline void univar4x4(float u, float B[4], float D[4]) { float t = u; float s = 1.0f - u; float A0 = s * s; float A1 = 2 * s * t; float A2 = t * t; B[0] = s * A0; B[1] = t * A0 + s * A1; B[2] = t * A1 + s * A2; B[3] = t * A2; if (D) { D[0] = - A0; D[1] = A0 - A1; D[2] = A1 - A2; D[3] = A2; } } #endif void evalBilinear(Far::PatchParam::BitField bits, float s, float t, Far::Index const * vertexIndices, VertexBufferDescriptor const & inDesc, float const * inQ, VertexBufferDescriptor const & outDesc, float * outQ, float * outDQ1, float * outDQ2) { assert( outQ and inDesc.length <= (outDesc.stride-outDesc.offset) ); float Q[4], dQ1[4], dQ2[4]; Far::GetBilinearWeights(bits, s, t, outQ ? Q:0, outDQ1 ? dQ1:0, outDQ2 ? dQ2:0); float const * inOffset = inQ + inDesc.offset; outQ += outDesc.offset; memset(outQ, 0, inDesc.length*sizeof(float)); if (outDQ1) { memset(outDQ1, 0, inDesc.length*sizeof(float)); } if (outDQ2) { memset(outDQ2, 0, inDesc.length*sizeof(float)); } for (int i=0; i<4; ++i) { float const * in = inOffset + vertexIndices[i]*inDesc.stride; for (int k=0; k= 0) ? inOffset + vertexIndices[index]*inDesc.stride : &CP[(-index-1)*inDesc.length]; for (int k=0; k2) { for (int k=0; k0); float const * diagonal = inOffset + idx_diagonal * inDesc.stride; for (int j=0; j0 and idx_diagonal>0 ); float const * neighbor = inOffset + idx_neighbor * inDesc.stride; diagonal = inOffset + idx_diagonal * inDesc.stride; for (int j=0; j 2) { float s1 = 3.0f - 2.0f*csf(n-3,2)-csf(np-3,2), s2 = 2.0f*csf(n-3,2), s3 = 3.0f -2.0f*cosf(2.0f*float(M_PI)/float(n)) - cosf(2.0f*float(M_PI)/float(nm)); for (int k=0, ofs=vofs; k