/*
CutrVelvet.cpp
RfM22.0
*/
#include <RixPattern.h>
#include <RixShadingUtils.h>
#include <RixPredefinedStrings.hpp>
class CutrVelvet : public RixPattern {
public:
CutrVelvet();
virtual ~CutrVelvet() { }
virtual int Init(RixContext &ctx, RtUString pluginpath);
virtual RixSCParamInfo const *GetParamTable();
virtual void Synchronize(RixContext &ctx, RixSCSyncMsg sync_msg,
RixParameterList const *plist) { }
virtual int CreateInstanceData(RixContext &ctx, RtUString const str,
RixParameterList const *plist, InstanceData *data)
{
return -1;
}
virtual void Finalize(RixContext &) { }
virtual int ComputeOutputParams(RixShadingContext const *ctx,
RtInt *noutputs,
OutputSpec **outputs,
RtPointer instanceData,
RixSCParamInfo const *ignored);
virtual bool Bake2dOutput(RixBakeContext const *ctx, Bake2dSpec &spec, RtPointer ptr) { return false; }
virtual bool Bake3dOutput(RixBakeContext const *ctx, Bake3dSpec &spec, RtPointer ptr) { return false; }
private:
RixMessages *m_msg;
RixShadeFunctions *m_shd; // Shading functions in RixInterfaces.h
RtFloat m_edge_width;
RtColorRGB m_edge_color;
RtFloat m_edge_brightness;
RtColorRGB m_base_color;
RtFloat m_base_brightness;
};
CutrVelvet::CutrVelvet():
m_msg(NULL),
m_shd(NULL),
m_edge_width(0),
m_edge_color(1,1,1),
m_edge_brightness(1),
m_base_color(1,1,1),
m_base_brightness(1)
{ }
int CutrVelvet::Init(RixContext &ctx, RtUString 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 *CutrVelvet::GetParamTable() {
static RixSCParamInfo s_ptable[] = {
// Output
RixSCParamInfo(RtUString("resultRGB"), k_RixSCColor, k_RixSCOutput),
// Inputs
RixSCParamInfo(RtUString("edge_width"), k_RixSCFloat),
RixSCParamInfo(RtUString("edge_color"), k_RixSCColor),
RixSCParamInfo(RtUString("edge_brightness"), k_RixSCFloat),
RixSCParamInfo(RtUString("base_color"), k_RixSCColor),
RixSCParamInfo(RtUString("base_brightness"), k_RixSCFloat),
RixSCParamInfo() // end of table
};
return &s_ptable[0];
}
enum paramIndex {
k_resultRGB = 0,
k_edge_width,
k_edge_color,
k_edge_brightness,
k_base_color,
k_base_brightness
};
int CutrVelvet::ComputeOutputParams(RixShadingContext const *ctx,
RtInt *noutputs,
OutputSpec **outputs,
RtPointer instanceData,
RixSCParamInfo const *ignored) {
// 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;
// Declare a pointer for each input then obtain their valuesusing EvalParam().
RtFloat const *edge_width;
RtColorRGB const *edge_color;
RtFloat const *edge_brightness;
RtColorRGB const *base_color;
RtFloat const *base_brightness;
ctx->EvalParam(k_edge_width, -1, &edge_width, &m_edge_width, varying);
ctx->EvalParam(k_edge_color, -1, &edge_color, &m_edge_color, varying);
ctx->EvalParam(k_edge_brightness, -1, &edge_brightness, &m_edge_brightness, varying);
ctx->EvalParam(k_base_color, -1, &base_color, &m_base_color, varying);
ctx->EvalParam(k_base_brightness, -1, &base_brightness, &m_base_brightness, varying);
// Assign an array of normalized shading normals to Nn.
RtNormal3 const *Nn;
ctx->GetBuiltinVar(RixShadingContext::k_Nn, &Nn);
// Assign an array of normalized view vectors to Vn.
RtVector3 const *Vn;
ctx->GetBuiltinVar(RixShadingContext::k_Vn, &Vn);
// Assign values to the outputs.
RtFloat dot;
for(int i = 0; i < ctx->numPts; i++) {
dot = 1.0 - Vn[i].Dot(Nn[i]);
dot = RixSmoothStep(1.0 - edge_width[i], 1.0, dot);
resultRGB[i] = RixMix(base_color[i] * base_brightness[i], edge_color[i] * edge_brightness[i], dot);
}
return 0;
}
RIX_PATTERNCREATE {
return new CutrVelvet();
}
RIX_PATTERNDESTROY {
delete((CutrVelvet*)pattern);
}