void IECoreArnold::RendererImplementation::procedural( IECore::Renderer::ProceduralPtr proc ) { Box3f bound = proc->bound(); if( bound.isEmpty() ) { return; } AtNode *procedural = AiNode( "procedural" ); if( ExternalProcedural *externalProc = dynamic_cast<ExternalProcedural *>( proc.get() ) ) { AiNodeSetStr( procedural, "dso", externalProc->fileName().c_str() ); ParameterAlgo::setParameters( procedural, externalProc->parameters() ); applyTransformToNode( procedural ); } else { // we have to transform the bound, as we're not applying the current transform to the // procedural node, but instead applying absolute transforms to the shapes the procedural // generates. if( bound != Procedural::noBound ) { Box3f transformedBound; for( size_t i = 0, e = m_transformStack.numSamples(); i < e; ++i ) { transformedBound.extendBy( transform( bound, m_transformStack.sample( i ) ) ); } bound = transformedBound; } AiNodeSetPtr( procedural, "funcptr", (void *)procLoader ); ProceduralData *data = new ProceduralData; data->procedural = proc; data->renderer = new IECoreArnold::Renderer( new RendererImplementation( *this ) ); AiNodeSetPtr( procedural, "userptr", data ); } if( bound != Procedural::noBound ) { AiNodeSetPnt( procedural, "min", bound.min.x, bound.min.y, bound.min.z ); AiNodeSetPnt( procedural, "max", bound.max.x, bound.max.y, bound.max.z ); } else { // No bound available - expand procedural immediately. AiNodeSetBool( procedural, "load_at_init", true ); } // we call addNode() rather than addShape() as we don't want to apply transforms and // shaders and attributes to procedurals. if we do, they override the things we set // on the nodes generated by the procedurals, which is frankly useless. addNode( procedural ); }
void IECoreArnold::RendererImplementation::procedural( IECore::Renderer::ProceduralPtr proc ) { Box3f bound = proc->bound(); if( bound.isEmpty() ) { return; } AtNode *node = NULL; std::string nodeType = "procedural"; if( const ExternalProcedural *externalProc = dynamic_cast<ExternalProcedural *>( proc.get() ) ) { // Allow a parameter "ai:nodeType" == "volume" to create a volume shape rather // than a procedural shape. Volume shapes provide "dso", "min" and "max" parameters // just as procedural shapes do, so the mapping is a fairly natural one. CompoundDataMap::const_iterator nodeTypeIt = externalProc->parameters().find( "ai:nodeType" ); if( nodeTypeIt != externalProc->parameters().end() && nodeTypeIt->second->isInstanceOf( StringData::staticTypeId() ) ) { nodeType = static_cast<const StringData *>( nodeTypeIt->second.get() )->readable(); } node = AiNode( nodeType.c_str() ); AiNodeSetStr( node, "dso", externalProc->fileName().c_str() ); ParameterAlgo::setParameters( node, externalProc->parameters() ); applyTransformToNode( node ); } else { node = AiNode( nodeType.c_str() ); // we have to transform the bound, as we're not applying the current transform to the // procedural node, but instead applying absolute transforms to the shapes the procedural // generates. if( bound != Procedural::noBound ) { Box3f transformedBound; for( size_t i = 0, e = m_transformStack.numSamples(); i < e; ++i ) { transformedBound.extendBy( transform( bound, m_transformStack.sample( i ) ) ); } bound = transformedBound; } AiNodeSetPtr( node, "funcptr", (void *)procLoader ); ProceduralData *data = new ProceduralData; data->procedural = proc; data->renderer = new IECoreArnold::Renderer( new RendererImplementation( *this ) ); AiNodeSetPtr( node, "userptr", data ); } if( bound != Procedural::noBound ) { AiNodeSetPnt( node, "min", bound.min.x, bound.min.y, bound.min.z ); AiNodeSetPnt( node, "max", bound.max.x, bound.max.y, bound.max.z ); } else { // No bound available - expand procedural immediately. AiNodeSetBool( node, "load_at_init", true ); } if( nodeType == "procedural" ) { // We call addNode() rather than addShape() as we don't want to apply transforms and // shaders and attributes to procedurals. If we do, they override the things we set // on the nodes generated by the procedurals, which is frankly useless. addNode( node ); } else { addShape( node ); } }
void IECoreRI::SXRendererImplementation::procedural( IECore::Renderer::ProceduralPtr proc ) { proc->render( m_parent ); }