/* 
 CutrBBones.cpp
 Generated by Cutter from:
     "/Users/malcolm/Documents/WebSite/FUNDZA_COM/cutter/devkit/rixpattern/CutrBBones.args"
 at 10.58:32am 9.11.2016
*/
#include <RixPattern.h> 
#include <RixShadingUtils.h>
#include <RixShading.h>
//#include <RixInterfaces.h>
#include <cstring>
//#include <cstdio>
//#include <sstream>
//#include <cmath>
  
class CutrBBones : public RixPattern {
public:
  
    CutrBBones();
    virtual ~CutrBBones() { }
    virtual int Init(RixContext &, char const *pluginpath);
    virtual RixSCParamInfo const *GetParamTable();
    virtual void Finalize(RixContext &) { }
    virtual int ComputeOutputParams(RixShadingContext const *ctx,
                                    RtInt *noutputs, 
                                    OutputSpec **outputs,
                                    RtConstPointer instanceData,
                                    RixSCParamInfo const *ignored);
    private:
        RixMessages *m_msg;
        RixShadeFunctions *m_shd;  // Shading functions in RixInterfaces.h
        RtColorRGB const m_rgb_connectable;
        RtFloat const m_s_cutoff;
  
    };
  
CutrBBones::CutrBBones():
    m_msg(NULL),
    m_shd(NULL),
    m_rgb_connectable(1,1,0),
    m_s_cutoff(0.35)
    { }
  
int CutrBBones::Init(RixContext &ctx, char const *pluginpath) {
    m_msg = (RixMessages*)ctx.GetRixInterface(k_RixMessages);
    m_shd = (RixShadeFunctions*)ctx.GetRixInterface(k_RixShadeFunctions);
  
    // Uncomment the next three lines if a rib Option will be queried.
    //RixRenderState *rstate = (RixRenderState*)ctx.GetRixInterface(k_RixRenderState);
    //RixRenderState::Type optType;
    //RtInt optNumValues, err;
    // Example of using messaging,
    //    m_msg->Info("%f\n", a_float_value);
    return (!m_msg) ? 1 : 0;
    }
  
RixSCParamInfo const *CutrBBones::GetParamTable() {
    static RixSCParamInfo s_ptable[] = {
        // Output
        RixSCParamInfo("resultRGB", k_RixSCColor, k_RixSCOutput),
        // Inputs
        RixSCParamInfo("rgb_connectable", k_RixSCColor),
        RixSCParamInfo("s_cutoff", k_RixSCFloat),
        RixSCParamInfo("PxrManifold", "manifold", k_RixSCStructBegin),
           RixSCParamInfo("Q", k_RixSCPoint),
           RixSCParamInfo("Qradius", k_RixSCFloat),
        RixSCParamInfo("PxrManifold", "manifold", k_RixSCStructEnd),
        RixSCParamInfo() // end of table
        };
    return &s_ptable[0];
    }
  
enum paramIndex {
    k_resultRGB = 0,
    k_rgb_connectable,
    k_s_cutoff,
    k_manifold,
        k_manifoldQ,
        k_manifoldQradius,
    k_manifoldEnd
    };
    
int CutrBBones::ComputeOutputParams(RixShadingContext const *ctx,
                                RtInt *noutputs, 
                                OutputSpec **outputs,
                                RtConstPointer instanceData,
                                RixSCParamInfo const *ignored) {
  
    // Uncomment the next three lines if a rib Attribute will be queried. Note
    // that Rib Options should be queried in the init() method - not here!
    //RixRenderState *rstate = (RixRenderState*)ctx->GetRixInterface(k_RixRenderState);
    //RixRenderState::Type attrType;
    //RtInt attrNumValues, err;
  
    // OUTPUTS BEGIN____________________________________
    // Allocate memory for the OutputSpec data structure.
    RixShadingContext::Allocator pool(ctx);
    OutputSpec *outSpec = pool.AllocForPattern<OutputSpec>(1);
    *outputs = outSpec;
  
    // Allocate memory for each output.
    RtColorRGB    *resultRGB = pool.AllocForPattern<RtColorRGB>(ctx->numPts);
  
    // Connect the output(s) to the OutputSpec.
    *noutputs = 1;
    outSpec[0].paramId = k_resultRGB;
    outSpec[0].detail = k_RixSCVarying;
    outSpec[0].value = resultRGB;
  
    // INPUTS BEGIN____________________________________
    bool varying = true;
    bool uniform = false;
    // Declare a pointer for each input then obtain their values
    // using EvalParam().
    RtColorRGB const *rgb_connectable;
    RtFloat const *s_cutoff;
  
    ctx->EvalParam(k_rgb_connectable, -1, &rgb_connectable, &m_rgb_connectable, varying);
    ctx->EvalParam(k_s_cutoff, -1, &s_cutoff, &m_s_cutoff, varying);
  
    // Prepare to read 'st' texture values from a connected manifold 
    // or from a 'st' primitive variable. 
    RixSCConnectionInfo cinfo;
    RixSCType type;
    RtPoint3 const *Q;
    RtFloat2 const *st, st_default(0,0);
    
    // Only if the manifold is connected can its Q[i].x and Q[i].y
    // texture coordinates be used.
    ctx->GetParamInfo(k_manifold, &type, &cinfo);
    if(cinfo == k_RixSCNetworkValue) 
        ctx->EvalParam(k_manifoldQ, -1, &Q);
    else
        ctx->GetPrimVar("st", st_default, &st);
    bool    isConnected = (cinfo == k_RixSCNetworkValue) ? true : false;
    int        row, col;
    float    s, t;
  
  
    // Assign values to the output(s).
    for(int i = 0; i < ctx->numPts; i++) {
        s = (isConnected) ? Q[i].x : st[i].x;
        t = (isConnected) ? Q[i].y : st[i].y;
        row = int(t);
        col = int(s);
        s = s - col;
        t = t - row;
        // For example, assign output based on the value of 's'
        if(s > 0.5) {
 
            resultRGB[i].r = rgb_connectable[i].r;
            resultRGB[i].g = rgb_connectable[i].g;
            resultRGB[i].b = rgb_connectable[i].b;
            }
        else
            {
            resultRGB[i].r = 1.0;
            resultRGB[i].g = 1.0;
            resultRGB[i].b = 1.0;
            }
        }
    return 0;
    }
RIX_PATTERNCREATE {
    return new CutrBBones();
    }
RIX_PATTERNDESTROY {
    delete((CutrBBones*)pattern);
    }