void SceneProcedural::render( RendererPtr renderer ) const { Context::Scope scopedContext( m_context ); /// \todo See above. try { // get all the attributes, and early out if we're not visibile ConstCompoundObjectPtr attributes = m_scenePlug->attributesPlug()->getValue(); const BoolData *visibilityData = attributes->member<BoolData>( "gaffer:visibility" ); if( visibilityData && !visibilityData->readable() ) { return; } // if we are visible then make an attribute block to contain everything, set the name // and get on with generating things. AttributeBlock attributeBlock( renderer ); std::string name = ""; for( ScenePlug::ScenePath::const_iterator it = m_scenePath.begin(), eIt = m_scenePath.end(); it != eIt; it++ ) { name += "/" + it->string(); } renderer->setAttribute( "name", new StringData( name ) ); // transform std::set<float> transformTimes; motionTimes( ( m_options.transformBlur && m_attributes.transformBlur ) ? m_attributes.transformBlurSegments : 0, transformTimes ); { ContextPtr timeContext = new Context( *m_context ); Context::Scope scopedTimeContext( timeContext ); MotionBlock motionBlock( renderer, transformTimes, transformTimes.size() > 1 ); for( std::set<float>::const_iterator it = transformTimes.begin(), eIt = transformTimes.end(); it != eIt; it++ ) { timeContext->setFrame( *it ); renderer->concatTransform( m_scenePlug->transformPlug()->getValue() ); } } // attributes for( CompoundObject::ObjectMap::const_iterator it = attributes->members().begin(), eIt = attributes->members().end(); it != eIt; it++ ) { if( const StateRenderable *s = runTimeCast<const StateRenderable>( it->second.get() ) ) { s->render( renderer ); } else if( const ObjectVector *o = runTimeCast<const ObjectVector>( it->second.get() ) ) { for( ObjectVector::MemberContainer::const_iterator it = o->members().begin(), eIt = o->members().end(); it != eIt; it++ ) { const StateRenderable *s = runTimeCast<const StateRenderable>( it->get() ); if( s ) { s->render( renderer ); } } } else if( const Data *d = runTimeCast<const Data>( it->second.get() ) ) { renderer->setAttribute( it->first, d ); } } // object std::set<float> deformationTimes; motionTimes( ( m_options.deformationBlur && m_attributes.deformationBlur ) ? m_attributes.deformationBlurSegments : 0, deformationTimes ); { ContextPtr timeContext = new Context( *m_context ); Context::Scope scopedTimeContext( timeContext ); unsigned timeIndex = 0; for( std::set<float>::const_iterator it = deformationTimes.begin(), eIt = deformationTimes.end(); it != eIt; it++, timeIndex++ ) { timeContext->setFrame( *it ); ConstObjectPtr object = m_scenePlug->objectPlug()->getValue(); if( const Primitive *primitive = runTimeCast<const Primitive>( object.get() ) ) { if( deformationTimes.size() > 1 && timeIndex == 0 ) { renderer->motionBegin( deformationTimes ); } primitive->render( renderer ); if( deformationTimes.size() > 1 && timeIndex == deformationTimes.size() - 1 ) { renderer->motionEnd(); } } else if( const Camera *camera = runTimeCast<const Camera>( object.get() ) ) { /// \todo This absolutely does not belong here, but until we have /// a mechanism for drawing manipulators, we don't have any other /// means of visualising the cameras. if( renderer->isInstanceOf( "IECoreGL::Renderer" ) ) { drawCamera( camera, renderer.get() ); } break; // no motion blur for these chappies. } else if( const Light *light = runTimeCast<const Light>( object.get() ) ) { /// \todo This doesn't belong here. if( renderer->isInstanceOf( "IECoreGL::Renderer" ) ) { drawLight( light, renderer.get() ); } break; // no motion blur for these chappies. } else if( const VisibleRenderable* renderable = runTimeCast< const VisibleRenderable >( object.get() ) ) { renderable->render( renderer ); break; // no motion blur for these chappies. } } } // children ConstInternedStringVectorDataPtr childNames = m_scenePlug->childNamesPlug()->getValue(); if( childNames->readable().size() ) { bool expand = true; if( m_pathsToExpand ) { expand = m_pathsToExpand->readable().match( m_scenePath ) & Filter::ExactMatch; } if( !expand ) { renderer->setAttribute( "gl:primitive:wireframe", new BoolData( true ) ); renderer->setAttribute( "gl:primitive:solid", new BoolData( false ) ); renderer->setAttribute( "gl:curvesPrimitive:useGLLines", new BoolData( true ) ); Box3f b = m_scenePlug->boundPlug()->getValue(); CurvesPrimitive::createBox( b )->render( renderer ); } else { ScenePlug::ScenePath childScenePath = m_scenePath; childScenePath.push_back( InternedString() ); // for the child name for( vector<InternedString>::const_iterator it=childNames->readable().begin(); it!=childNames->readable().end(); it++ ) { childScenePath[m_scenePath.size()] = *it; renderer->setAttribute( "name", new StringData( *it ) ); renderer->procedural( new SceneProcedural( *this, childScenePath ) ); } } } } catch( const std::exception &e ) { IECore::msg( IECore::Msg::Error, "SceneProcedural::render()", e.what() ); } }