//-***************************************************************************** // // Copyright (c) 2009-2011, // Sony Pictures Imageworks Inc. and // Industrial Light & Magic, a division of Lucasfilm Entertainment Company Ltd. // // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Sony Pictures Imageworks, nor // Industrial Light & Magic, nor the names of their contributors may be used // to endorse or promote products derived from this software without specific // prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // //-***************************************************************************** #include "ArbGeomParams.h" #include 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 ""; //arnold doesn't support facevarying user-data 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: // For now, only support the above types return ""; } return buffer.str(); } //-***************************************************************************** template void AddArbitraryGeomParam( ICompoundProperty & parent, const PropertyHeader &propHeader, ISampleSelector &sampleSelector, AtNode * primNode, int arnoldAPIType) { T param( parent, propHeader.getName() ); if ( !param.valid() ) { //TODO error message? return; } std::string declStr = GetArnoldTypeString( param.getScope(), arnoldAPIType ); if ( declStr.empty() ) { return; } // TODO For now, don't support user-defined arrays. // It's reasonable to support these for kConstantScope if ( param.getArrayExtent() > 1 ) { return; } if ( !AiNodeDeclare( primNode, param.getName().c_str(), declStr.c_str() ) ) { //TODO, AiWarning return; } if ( param.getScope() == kConstantScope || param.getScope() == kUnknownScope) { //Set scalars directly based on arnoldAPIType since we're //not yet support array types here 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( valueSample->get() )[0] ); break; case AI_TYPE_FLOAT: AiNodeSetFlt( primNode, param.getName().c_str(), reinterpret_cast( valueSample->get() )[0] ); break; case AI_TYPE_STRING: AiNodeSetStr( primNode, param.getName().c_str(), reinterpret_cast( valueSample->get() )[0].c_str() ); break; case AI_TYPE_RGB: { const float32_t * data = reinterpret_cast( 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( 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( 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( 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( valueSample->get() ); AiNodeSetPnt2( primNode, param.getName().c_str(), data[0], data[1] ); break; } case AI_TYPE_MATRIX: { const float32_t * data = reinterpret_cast( 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: // For now, only support the above types break; } } else { // Always set arrays for other scopes 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() ) { //TODO error message? return; } std::string declStr = GetArnoldTypeString( param.getScope(), AI_TYPE_STRING ); if ( declStr.empty() ) { return; } // TODO, remove this restriction and support arrays for constant values if ( param.getArrayExtent() > 1 ) { return; } if ( !AiNodeDeclare( primNode, param.getName().c_str(), declStr.c_str() ) ) { //TODO, AiWarning 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( valueSample->get() )[0].c_str() ); } else { std::vector 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] ) ); } } //-***************************************************************************** //UserDefDeclare(node, name.c_str(), userType.c_str())) continue; //SetUserData(node, name.c_str(), dataSize, apiType, dataStart); void AddArbitraryGeomParams( ICompoundProperty &parent, ISampleSelector &sampleSelector, AtNode * primNode, const std::set * 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( parent, propHeader, sampleSelector, primNode, AI_TYPE_FLOAT); } else if ( IInt32GeomParam::matches( propHeader ) ) { AddArbitraryGeomParam( parent, propHeader, sampleSelector, primNode, AI_TYPE_INT); } else if ( IStringGeomParam::matches( propHeader ) ) { AddArbitraryStringGeomParam( parent, propHeader, sampleSelector, primNode); } else if ( IV2fGeomParam::matches( propHeader ) ) { AddArbitraryGeomParam( parent, propHeader, sampleSelector, primNode, AI_TYPE_POINT2); } else if ( IV3fGeomParam::matches( propHeader ) ) { AddArbitraryGeomParam( parent, propHeader, sampleSelector, primNode, AI_TYPE_VECTOR); } else if ( IP3fGeomParam::matches( propHeader ) ) { AddArbitraryGeomParam( parent, propHeader, sampleSelector, primNode, AI_TYPE_POINT); } else if ( IN3fGeomParam::matches( propHeader ) ) { AddArbitraryGeomParam( parent, propHeader, sampleSelector, primNode, AI_TYPE_VECTOR); } else if ( IC3fGeomParam::matches( propHeader ) ) { AddArbitraryGeomParam( parent, propHeader, sampleSelector, primNode, AI_TYPE_RGB); } else if ( IC4fGeomParam::matches( propHeader ) ) { AddArbitraryGeomParam( parent, propHeader, sampleSelector, primNode, AI_TYPE_RGBA); } if ( IM44fGeomParam::matches( propHeader ) ) { AddArbitraryGeomParam( parent, propHeader, sampleSelector, primNode, AI_TYPE_MATRIX); } } }