#include "ArbGeomParams.h"
#include <sstream>
std::string GetArnoldTypeString( GeometryScope scope, int arnoldAPIType)
{
std::ostringstream buffer;
switch (scope)
{
case kUniformScope:
buffer << "uniform";
break;
case kVaryingScope:
case kVertexScope:
buffer << "varying";
break;
case kFacevaryingScope:
return "";
case kConstantScope:
default:
buffer << "constant";
}
buffer << " ";
switch ( arnoldAPIType )
{
case AI_TYPE_INT:
buffer << "INT";
break;
case AI_TYPE_FLOAT:
buffer << "FLOAT";
break;
case AI_TYPE_STRING:
buffer << "STRING";
break;
case AI_TYPE_RGB:
buffer << "RGB";
break;
case AI_TYPE_RGBA:
buffer << "RGBA";
break;
case AI_TYPE_POINT:
buffer << "POINT";
break;
case AI_TYPE_VECTOR:
buffer << "VECTOR";
break;
case AI_TYPE_POINT2:
buffer << "POINT2";
break;
case AI_TYPE_MATRIX:
buffer << "MATRIX";
break;
default:
return "";
}
return buffer.str();
}
template <typename T>
void AddArbitraryGeomParam( ICompoundProperty & parent,
const PropertyHeader &propHeader,
ISampleSelector &sampleSelector,
AtNode * primNode,
int arnoldAPIType)
{
T param( parent, propHeader.getName() );
if ( !param.valid() )
{
return;
}
std::string declStr = GetArnoldTypeString( param.getScope(),
arnoldAPIType );
if ( declStr.empty() )
{
return;
}
if ( param.getArrayExtent() > 1 )
{
return;
}
if ( !AiNodeDeclare( primNode, param.getName().c_str(), declStr.c_str() ) )
{
return;
}
if ( param.getScope() == kConstantScope ||
param.getScope() == kUnknownScope)
{
typename T::prop_type::sample_ptr_type valueSample =
param.getExpandedValue( sampleSelector ).getVals();
switch ( arnoldAPIType )
{
case AI_TYPE_INT:
AiNodeSetInt( primNode, param.getName().c_str(),
reinterpret_cast<const int32_t *>(
valueSample->get() )[0] );
break;
case AI_TYPE_FLOAT:
AiNodeSetFlt( primNode, param.getName().c_str(),
reinterpret_cast<const float32_t *>(
valueSample->get() )[0] );
break;
case AI_TYPE_STRING:
AiNodeSetStr( primNode, param.getName().c_str(),
reinterpret_cast<const std::string *>(
valueSample->get() )[0].c_str() );
break;
case AI_TYPE_RGB:
{
const float32_t * data =
reinterpret_cast<const float32_t *>(
valueSample->get() );
AiNodeSetRGB( primNode, param.getName().c_str(),
data[0], data[1], data[2]);
break;
}
case AI_TYPE_RGBA:
{
const float32_t * data =
reinterpret_cast<const float32_t *>(
valueSample->get() );
AiNodeSetRGBA( primNode, param.getName().c_str(),
data[0], data[1], data[2], data[3]);
break;
}
case AI_TYPE_POINT:
{
const float32_t * data =
reinterpret_cast<const float32_t *>(
valueSample->get() );
AiNodeSetPnt( primNode, param.getName().c_str(),
data[0], data[1], data[2]);
break;
}
case AI_TYPE_VECTOR:
{
const float32_t * data =
reinterpret_cast<const float32_t *>(
valueSample->get() );
AiNodeSetVec( primNode, param.getName().c_str(),
data[0], data[1], data[2] );
break;
}
case AI_TYPE_POINT2:
{
const float32_t * data =
reinterpret_cast<const float32_t *>(
valueSample->get() );
AiNodeSetPnt2( primNode, param.getName().c_str(),
data[0], data[1] );
break;
}
case AI_TYPE_MATRIX:
{
const float32_t * data =
reinterpret_cast<const float32_t *>(
valueSample->get() );
AtMatrix m;
for ( size_t i = 0; i < 16; ++i )
{
*((&m[0][0])+i) = data[i];
}
AiNodeSetMatrix( primNode, param.getName().c_str(), m);
break;
}
default:
break;
}
}
else
{
typename T::prop_type::sample_ptr_type valueSample =
param.getExpandedValue( sampleSelector ).getVals();
AiNodeSetArray( primNode, param.getName().c_str(),
ArrayConvert( valueSample->size(), 1, arnoldAPIType,
(void *) valueSample->get() ) );
}
}
void AddArbitraryStringGeomParam( ICompoundProperty & parent,
const PropertyHeader &propHeader,
ISampleSelector &sampleSelector,
AtNode * primNode)
{
IStringGeomParam param( parent, propHeader.getName() );
if ( !param.valid() )
{
return;
}
std::string declStr = GetArnoldTypeString( param.getScope(),
AI_TYPE_STRING );
if ( declStr.empty() )
{
return;
}
if ( param.getArrayExtent() > 1 )
{
return;
}
if ( !AiNodeDeclare( primNode, param.getName().c_str(), declStr.c_str() ) )
{
return;
}
IStringGeomParam::prop_type::sample_ptr_type valueSample =
param.getExpandedValue( sampleSelector ).getVals();
if ( param.getScope() == kConstantScope ||
param.getScope() == kUnknownScope)
{
AiNodeSetStr( primNode, param.getName().c_str(),
reinterpret_cast<const std::string *>(
valueSample->get() )[0].c_str() );
}
else
{
std::vector<const char *> strPtrs;
strPtrs.reserve( valueSample->size() );
for ( size_t i = 0; i < valueSample->size(); ++i )
{
strPtrs.push_back( valueSample->get()[i].c_str() );
}
AiNodeSetArray( primNode, param.getName().c_str(),
ArrayConvert( valueSample->size(), 1, AI_TYPE_STRING,
(void *) &strPtrs[0] ) );
}
}
void AddArbitraryGeomParams( ICompoundProperty &parent,
ISampleSelector &sampleSelector,
AtNode * primNode,
const std::set<std::string> * excludeNames
)
{
if ( primNode == NULL || !parent.valid() )
{
return;
}
for ( size_t i = 0; i < parent.getNumProperties(); ++i )
{
const PropertyHeader &propHeader = parent.getPropertyHeader( i );
const std::string &propName = propHeader.getName();
if (propName.empty()
|| ( excludeNames
&& excludeNames->find( propName ) != excludeNames->end() ) )
{
continue;
}
if ( IFloatGeomParam::matches( propHeader ) )
{
AddArbitraryGeomParam<IFloatGeomParam>(
parent,
propHeader,
sampleSelector,
primNode,
AI_TYPE_FLOAT);
}
else if ( IInt32GeomParam::matches( propHeader ) )
{
AddArbitraryGeomParam<IInt32GeomParam>(
parent,
propHeader,
sampleSelector,
primNode,
AI_TYPE_INT);
}
else if ( IStringGeomParam::matches( propHeader ) )
{
AddArbitraryStringGeomParam(
parent,
propHeader,
sampleSelector,
primNode);
}
else if ( IV2fGeomParam::matches( propHeader ) )
{
AddArbitraryGeomParam<IV2fGeomParam>(
parent,
propHeader,
sampleSelector,
primNode,
AI_TYPE_POINT2);
}
else if ( IV3fGeomParam::matches( propHeader ) )
{
AddArbitraryGeomParam<IV3fGeomParam>(
parent,
propHeader,
sampleSelector,
primNode,
AI_TYPE_VECTOR);
}
else if ( IP3fGeomParam::matches( propHeader ) )
{
AddArbitraryGeomParam<IP3fGeomParam>(
parent,
propHeader,
sampleSelector,
primNode,
AI_TYPE_POINT);
}
else if ( IN3fGeomParam::matches( propHeader ) )
{
AddArbitraryGeomParam<IN3fGeomParam>(
parent,
propHeader,
sampleSelector,
primNode,
AI_TYPE_VECTOR);
}
else if ( IC3fGeomParam::matches( propHeader ) )
{
AddArbitraryGeomParam<IC3fGeomParam>(
parent,
propHeader,
sampleSelector,
primNode,
AI_TYPE_RGB);
}
else if ( IC4fGeomParam::matches( propHeader ) )
{
AddArbitraryGeomParam<IC4fGeomParam>(
parent,
propHeader,
sampleSelector,
primNode,
AI_TYPE_RGBA);
}
if ( IM44fGeomParam::matches( propHeader ) )
{
AddArbitraryGeomParam<IM44fGeomParam>(
parent,
propHeader,
sampleSelector,
primNode,
AI_TYPE_MATRIX);
}
}
}