#include #include #include #include #include typedef OpenSubdiv::Far::PrimvarRefiner PrimvarRefiner; typedef OpenSubdiv::Far::TopologyRefiner TopologyRefiner; template struct Primvar { float v[N]; void Clear() { for (int i = 0; i < N; ++i) { v[i] = 0.0f; } } void AddWithWeight(const Primvar& p, float weight) { for (int i = 0; i < N; ++i) { v[i] += p.v[i] * weight; } } }; extern "C" { PrimvarRefiner* PrimvarRefiner_create(TopologyRefiner* tr) { return new PrimvarRefiner(*tr); } // FIXME: { if the TopologyRefiner is never fed to a PrimvarRefiner it will // leak? void PrimvarRefiner_destroy(PrimvarRefiner* pr) { delete pr; } const TopologyRefiner* PrimvarRefiner_GetTopologyRefiner(PrimvarRefiner* pr) { return &pr->GetTopologyRefiner(); } void PrimvarRefiner_Interpolate( PrimvarRefiner* pr, int num_elements, int level, float* src, float* dst ) { Primvar<1>* dst1; Primvar<2>* dst2; Primvar<3>* dst3; Primvar<4>* dst4; switch (num_elements) { case 1: { dst1 = (Primvar<1>*)dst; pr->Interpolate(level, (Primvar<1>*)src, dst1); break; } case 2: { dst2 = (Primvar<2>*)dst; pr->Interpolate(level, (Primvar<2>*)src, dst2); break; } case 3: { dst3 = (Primvar<3>*)dst; pr->Interpolate(level, (Primvar<3>*)src, dst3); break; } case 4: { dst4 = (Primvar<4>*)dst; pr->Interpolate(level, (Primvar<4>*)src, dst4); break; } default: { printf("Invalid num elements for Interpolate: { %d\n", num_elements); std::terminate(); } } } void PrimvarRefiner_InterpolateVarying( PrimvarRefiner* pr, int num_elements, int level, float* src, float* dst ) { Primvar<1>* dst1; Primvar<2>* dst2; Primvar<3>* dst3; Primvar<4>* dst4; switch (num_elements) { case 1: { dst1 = (Primvar<1>*)dst; pr->InterpolateVarying(level, (Primvar<1>*)src, dst1); break; } case 2: { dst2 = (Primvar<2>*)dst; pr->InterpolateVarying(level, (Primvar<2>*)src, dst2); break; } case 3: { dst3 = (Primvar<3>*)dst; pr->InterpolateVarying(level, (Primvar<3>*)src, dst3); break; } case 4: { dst4 = (Primvar<4>*)dst; pr->InterpolateVarying(level, (Primvar<4>*)src, dst4); break; } default: { printf("Invalid num elements for InterpolateVarying: { %d\n", num_elements); std::terminate(); } } } void PrimvarRefiner_InterpolateFaceUniform( PrimvarRefiner* pr, int num_elements, int level, float* src, float* dst ) { Primvar<1>* dst1; Primvar<2>* dst2; Primvar<3>* dst3; Primvar<4>* dst4; switch (num_elements) { case 1: { dst1 = (Primvar<1>*)dst; pr->InterpolateFaceUniform(level, (Primvar<1>*)src, dst1); break; } case 2: { dst2 = (Primvar<2>*)dst; pr->InterpolateFaceUniform(level, (Primvar<2>*)src, dst2); break; } case 3: { dst3 = (Primvar<3>*)dst; pr->InterpolateFaceUniform(level, (Primvar<3>*)src, dst3); break; } case 4: { dst4 = (Primvar<4>*)dst; pr->InterpolateFaceUniform(level, (Primvar<4>*)src, dst4); break; } default: { printf("Invalid num elements for InterpolateFaceUniform: { %d\n", num_elements); std::terminate(); } } } void PrimvarRefiner_InterpolateFaceVarying( PrimvarRefiner* pr, int num_elements, int level, float* src, float* dst ) { Primvar<1>* dst1; Primvar<2>* dst2; Primvar<3>* dst3; Primvar<4>* dst4; switch (num_elements) { case 1: { dst1 = (Primvar<1>*)dst; pr->InterpolateFaceVarying(level, (Primvar<1>*)src, dst1); break; } case 2: { dst2 = (Primvar<2>*)dst; pr->InterpolateFaceVarying(level, (Primvar<2>*)src, dst2); break; } case 3: { dst3 = (Primvar<3>*)dst; pr->InterpolateFaceVarying(level, (Primvar<3>*)src, dst3); break; } case 4: { dst4 = (Primvar<4>*)dst; pr->InterpolateFaceVarying(level, (Primvar<4>*)src, dst4); break; } default: { printf("Invalid num elements for InterpolateFaceVarying: { %d\n", num_elements); std::terminate(); } } } }