//-***************************************************************************** void AddArbitraryStringPropertyToParamListBuilder( ICompoundProperty &parent, const PropertyHeader &propHeader, ISampleSelector &sampleSelector, ParamListBuilder &ParamListBuilder ) { IStringArrayProperty prop( parent, propHeader.getName() ); if ( ! prop.valid() ) { //error message? return; } std::string rmanType = GetPrmanScopeString( GetGeometryScope( propHeader.getMetaData() ) ) + " "; rmanType += "string " + propHeader.getName(); StringArraySamplePtr propSample = prop.getValue( sampleSelector ); RtPointer dataStart = NULL; for ( size_t i = 0; i < propSample->size(); ++i ) { RtPointer data = ParamListBuilder.addStringValue( (*propSample)[i] ); if ( i == 0 ) { dataStart = data; } } ParamListBuilder.add(rmanType, dataStart, propSample); }
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<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(), AiArrayConvert( valueSample->size(), 1, AI_TYPE_STRING, (void *) &strPtrs[0] ) ); } }
//-***************************************************************************** void visitProperties( ICompoundProperty iParent, std::string &ioIndent ) { std::string oldIndent = ioIndent; for ( size_t i = 0 ; i < iParent.getNumProperties() ; i++ ) { PropertyHeader header = iParent.getPropertyHeader( i ); if ( header.isCompound() ) { visitCompoundProperty( ICompoundProperty( iParent, header.getName() ), ioIndent ); } else if ( header.isScalar() ) { visitSimpleProperty( IScalarProperty( iParent, header.getName() ), ioIndent ); } else { assert( header.isArray() ); visitSimpleProperty( IArrayProperty( iParent, header.getName() ), ioIndent ); } } ioIndent = oldIndent; }
void AddArbitraryPropertyToParamListBuilder( ICompoundProperty & parent, const PropertyHeader &propHeader, ISampleSelector &sampleSelector, const std::string &rmanBaseType, ParamListBuilder &ParamListBuilder ) { T prop( parent, propHeader.getName() ); if ( ! prop.valid() ) { //TODO error message? return; } std::string rmanType = GetPrmanScopeString( GetGeometryScope( propHeader.getMetaData() ) ) + " "; rmanType += rmanBaseType + " " + propHeader.getName(); typename T::sample_ptr_type propSample = prop.getValue( sampleSelector ); ParamListBuilder.add( rmanType, (RtPointer)propSample->get(), propSample ); }
//-***************************************************************************** void Example1_MeshIn() { IArchive archive( Alembic::AbcCoreHDF5::ReadArchive(), "subD1.abc" ); std::cout << "Reading: " << archive.getName() << std::endl; IGeomBaseObject geomBase( IObject( archive, kTop ), "subd" ); TESTING_ASSERT( geomBase.getSchema().getSelfBoundsProperty().valid() ); ISubD meshyObj( IObject( archive, kTop ), "subd", ErrorHandler::kNoisyNoopPolicy ); ISubDSchema &mesh = meshyObj.getSchema(); TESTING_ASSERT( mesh.getErrorHandlerPolicy() == ErrorHandler::kNoisyNoopPolicy ); TESTING_ASSERT( mesh.getUVsParam().getValueProperty().getErrorHandlerPolicy() == ErrorHandler::kNoisyNoopPolicy ); TESTING_ASSERT( mesh.getInterpolateBoundaryProperty().getErrorHandlerPolicy() == ErrorHandler::kNoisyNoopPolicy ); TESTING_ASSERT( 3 == mesh.getNumSamples() ); // UVs IV2fGeomParam uv = mesh.getUVsParam(); TESTING_ASSERT( ! uv.isIndexed() ); // we can fake like the UVs are indexed IV2fGeomParam::Sample uvsamp = uv.getIndexedValue(); TESTING_ASSERT( (*(uvsamp.getIndices()))[1] == 1 ); V2f uv2 = (*(uvsamp.getVals()))[2]; TESTING_ASSERT( uv2 == V2f( 1.0f, 1.0f ) ); std::cout << "2th UV: " << uv2 << std::endl; // get the 1th sample by value ISubDSchema::Sample samp1 = mesh.getValue( 1 ); IGeomBase::Sample baseSamp = geomBase.getSchema().getValue( 1 ); std::cout << "bounds: " << samp1.getSelfBounds().min << ", " << samp1.getSelfBounds().max << std::endl; TESTING_ASSERT( samp1.getSelfBounds().min == V3d( -1.0, -1.0, -1.0 ) ); TESTING_ASSERT( samp1.getSelfBounds().max == V3d( 1.0, 1.0, 1.0 ) ); TESTING_ASSERT( baseSamp.getSelfBounds().min == V3d( -1.0, -1.0, -1.0 ) ); TESTING_ASSERT( baseSamp.getSelfBounds().max == V3d( 1.0, 1.0, 1.0 ) ); for ( size_t i = 0 ; i < samp1.getCreaseSharpnesses()->size() ; ++i ) { std::cout << "crease sharpness[" << i << "]: " << (*(samp1.getCreaseSharpnesses()))[i] << std::endl; TESTING_ASSERT( 0.5 == (*(samp1.getCreaseSharpnesses()))[i] ); } for ( size_t i = 0 ; i < samp1.getCornerSharpnesses()->size() ; ++i ) { std::cout << "corner sharpness[" << i << "]: " << (*(samp1.getCornerSharpnesses()))[i] << std::endl; TESTING_ASSERT( 10.0 == (*(samp1.getCornerSharpnesses()))[i] ); } for ( size_t i = 0 ; i < samp1.getVelocities()->size() ; ++i ) { V3f veloc( g_veloc[i*3], g_veloc[i*3+1], g_veloc[i*3+2] ); std::cout << "velocities[" << i << "]: " << (*(samp1.getVelocities()))[i] << std::endl; TESTING_ASSERT( veloc == (*(samp1.getVelocities()))[i] ); } // test the second sample has '1' as the interpolate boundary value TESTING_ASSERT( 1 == samp1.getInterpolateBoundary() ); std::cout << "Interpolate boundary at 1th sample: " << samp1.getInterpolateBoundary() << std::endl; // get the twoth sample by reference ISubDSchema::Sample samp2; mesh.get( samp2, 2 ); TESTING_ASSERT( samp2.getSelfBounds().min == V3d( -1.0, -1.0, -1.0 ) ); TESTING_ASSERT( samp2.getSelfBounds().max == V3d( 1.0, 1.0, 1.0 ) ); TESTING_ASSERT( 0 == samp2.getInterpolateBoundary() ); std::cout << "Interpolate boundary at 2th sample: " << samp2.getInterpolateBoundary() << std::endl; std::cout << "Mesh num vertices: " << samp2.getPositions()->size() << std::endl; std::cout << "0th vertex from the mesh sample: " << (*(samp2.getPositions()))[0] << std::endl; std::cout << "0th vertex from the mesh sample with get method: " << samp2.getPositions()->get()[0] << std::endl; ICompoundProperty arbattrs = mesh.getArbGeomParams(); // This better exist since we wrote custom attr called color to it TESTING_ASSERT( arbattrs ); for (int i = 0; i < 2; ++ i) { PropertyHeader p = arbattrs.getPropertyHeader(i); TESTING_ASSERT( IC3fGeomParam::matches( p ) ); TESTING_ASSERT( OC3fGeomParam::matches( p ) ); TESTING_ASSERT( ! IC3cGeomParam::matches( p ) ); TESTING_ASSERT( ! OC3cGeomParam::matches( p ) ); TESTING_ASSERT( ! IInt32GeomParam::matches( p ) ); TESTING_ASSERT( ! IFloatGeomParam::matches( p ) ); TESTING_ASSERT( ! IDoubleGeomParam::matches( p ) ); TESTING_ASSERT( ! IV3iGeomParam::matches( p ) ); TESTING_ASSERT( ! IV3fGeomParam::matches( p ) ); if ( p.getName() == "color" ) { IC3fGeomParam color(arbattrs, "color"); TESTING_ASSERT( color.getValueProperty().isScalarLike() ); IC3fGeomParam::Sample cSamp0, cSamp1; color.getExpanded(cSamp0, 0); color.getExpanded(cSamp1, 1); TESTING_ASSERT( (*(cSamp0.getVals()))[0] == C3f( 1.0, 0.0, 0.0 ) ); TESTING_ASSERT( (*(cSamp1.getVals()))[0] == C3f( 1.0, 0.0, 1.0 ) ); } else if ( p.getName() == "colori" ) { IC3fGeomParam color(arbattrs, "colori"); TESTING_ASSERT( !color.getValueProperty().isScalarLike() ); IC3fGeomParam::Sample cSamp; color.getIndexed( cSamp ); TESTING_ASSERT( cSamp.getScope() == kFacevaryingScope ); TESTING_ASSERT( cSamp.getVals()->size() == 3 ); TESTING_ASSERT( (*cSamp.getVals())[0] == C3f( 0.0, 1.0, 1.0 ) ); TESTING_ASSERT( (*cSamp.getVals())[1] == C3f( 1.0, 0.0, 1.0 ) ); TESTING_ASSERT( (*cSamp.getVals())[2] == C3f( 1.0, 1.0, 0.0 ) ); Alembic::Util::uint32_t indices[24] = { 2, 2, 1, 1, 0, 0, 1, 2, 1, 1, 1, 0, 0, 0, 2, 2, 0, 0, 0, 2, 2, 2, 1, 1}; for (int j = 0; j < 24; ++j) { TESTING_ASSERT( (*cSamp.getIndices())[j] == indices[j] ); } } } }
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<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_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_VECTOR2: { const float32_t * data = reinterpret_cast<const float32_t *>( valueSample->get() ); AiNodeSetVec2( 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: // 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(), AiArrayConvert( valueSample->size(), 1, arnoldAPIType, (void *) valueSample->get() ) ); } }