opensubdiv-petite-sys 0.3.1

Low-level wrapper around parts of Pixar’s OpenSubdiv
Documentation
#include <opensubdiv/far/primvarRefiner.h>
#include <opensubdiv/sdc/options.h>
#include <opensubdiv/sdc/types.h>

#include <exception>
#include <stdio.h>

typedef OpenSubdiv::Far::PrimvarRefiner PrimvarRefiner;
typedef OpenSubdiv::Far::TopologyRefiner TopologyRefiner;

template <int N> 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();
        }
        }
    }
}