예제 #1
0
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() );
	}	
}