IECore::CameraPtr GafferScene::camera( const ScenePlug *scene, const ScenePlug::ScenePath &cameraPath, const IECore::CompoundObject *globals ) { ConstCompoundObjectPtr computedGlobals; if( !globals ) { computedGlobals = scene->globalsPlug()->getValue(); globals = computedGlobals.get(); } std::string cameraName; ScenePlug::pathToString( cameraPath, cameraName ); if( !exists( scene, cameraPath ) ) { throw IECore::Exception( "Camera \"" + cameraName + "\" does not exist" ); } IECore::ConstCameraPtr constCamera = runTimeCast<const IECore::Camera>( scene->object( cameraPath ) ); if( !constCamera ) { std::string path; ScenePlug::pathToString( cameraPath, path ); throw IECore::Exception( "Location \"" + cameraName + "\" is not a camera" ); } IECore::CameraPtr camera = constCamera->copy(); camera->setName( cameraName ); const BoolData *cameraBlurData = globals->member<BoolData>( "option:render:cameraBlur" ); const bool cameraBlur = cameraBlurData ? cameraBlurData->readable() : false; camera->setTransform( transform( scene, cameraPath, shutter( globals ), cameraBlur ) ); applyCameraGlobals( camera.get(), globals ); return camera; }
void outputScene( const ScenePlug *scene, IECore::Renderer *renderer ) { ConstCompoundObjectPtr globals = scene->globalsPlug()->getValue(); outputOptions( globals.get(), renderer ); outputOutputs( globals.get(), renderer ); outputCamera( scene, globals.get(), renderer ); { WorldBlock world( renderer ); outputGlobalAttributes( globals.get(), renderer ); outputCoordinateSystems( scene, globals.get(), renderer ); outputLights( scene, globals.get(), renderer ); SceneProceduralPtr proc = new SceneProcedural( scene, Context::current() ); renderer->procedural( proc ); } }
void ExecutableRender::execute() const { const ScenePlug *scene = inPlug()->getInput<ScenePlug>(); if( !scene ) { throw IECore::Exception( "No input scene" ); } ConstCompoundObjectPtr globals = scene->globalsPlug()->getValue(); RendererAlgo::createDisplayDirectories( globals.get() ); // Scoping the lifetime of the renderer so that // the destructor is run before we run the system // command. This can be essential for renderman // renders, where the rib stream may not be flushed // to disk before RiEnd is called. { IECore::RendererPtr renderer = createRenderer(); RendererAlgo::outputOptions( globals.get(), renderer.get() ); RendererAlgo::outputOutputs( globals.get(), renderer.get() ); RendererAlgo::outputCameras( scene, globals.get(), renderer.get() ); RendererAlgo::outputClippingPlanes( scene, globals.get(), renderer.get() ); { WorldBlock world( renderer ); RendererAlgo::outputGlobalAttributes( globals.get(), renderer.get() ); RendererAlgo::outputCoordinateSystems( scene, globals.get(), renderer.get() ); RendererAlgo::outputLights( scene, globals.get(), renderer.get() ); outputWorldProcedural( scene, renderer.get() ); } } }
void ToNukeGeometryConverter::convert( GeometryList &geoList ) const { int objIndex = m_objIndexParameter->getNumericValue(); if ( objIndex == -1 ) { objIndex = (int)geoList.objects(); } geoList.add_object(objIndex); ConstCompoundObjectPtr operands = parameters()->getTypedValidatedValue<CompoundObject>(); doConversion( srcParameter()->getValidatedValue(), geoList, objIndex, operands.get() ); }
void SceneWriter::writeLocation( const GafferScene::ScenePlug *scene, const ScenePlug::ScenePath &scenePath, Context *context, IECore::SceneInterface *output, double time ) const { context->set( ScenePlug::scenePathContextName, scenePath ); ConstCompoundObjectPtr attributes = scene->attributesPlug()->getValue(); for( CompoundObject::ObjectMap::const_iterator it = attributes->members().begin(), eIt = attributes->members().end(); it != eIt; it++ ) { output->writeAttribute( it->first, it->second.get(), time ); } if( scenePath.empty() ) { ConstCompoundObjectPtr globals = scene->globalsPlug()->getValue(); output->writeAttribute( "gaffer:globals", globals.get(), time ); } ConstObjectPtr object = scene->objectPlug()->getValue(); if( object->typeId() != IECore::NullObjectTypeId && scenePath.size() > 0 ) { output->writeObject( object.get(), time ); } Imath::Box3f b = scene->boundPlug()->getValue(); output->writeBound( Imath::Box3d( Imath::V3f( b.min ), Imath::V3f( b.max ) ), time ); if( scenePath.size() ) { Imath::M44f t = scene->transformPlug()->getValue(); Imath::M44d transform( t[0][0], t[0][1], t[0][2], t[0][3], t[1][0], t[1][1], t[1][2], t[1][3], t[2][0], t[2][1], t[2][2], t[2][3], t[3][0], t[3][1], t[3][2], t[3][3] ); output->writeTransform( new IECore::M44dData( transform ), time ); } ConstInternedStringVectorDataPtr childNames = scene->childNamesPlug()->getValue(); ScenePlug::ScenePath childScenePath = scenePath; childScenePath.push_back( InternedString() ); for( vector<InternedString>::const_iterator it=childNames->readable().begin(); it!=childNames->readable().end(); it++ ) { childScenePath[scenePath.size()] = *it; SceneInterfacePtr outputChild = output->child( *it, SceneInterface::CreateIfMissing ); writeLocation( scene, childScenePath, context, outputChild.get(), time ); } }
IECore::ImagePrimitivePtr ImagePlug::image() const { Format format = formatPlug()->getValue(); Box2i dataWindow = dataWindowPlug()->getValue(); Box2i newDataWindow( Imath::V2i(0) ); if( dataWindow.isEmpty() ) { dataWindow = Box2i( Imath::V2i(0) ); } else { newDataWindow = format.yDownToFormatSpace( dataWindow ); } // use the default format if we don't have an explicit one. /// \todo: remove this once FormatPlug is handling it for /// us during ExecutableNode::execute (see issue #887). if( format.getDisplayWindow().isEmpty() ) { format = Context::current()->get<Format>( Format::defaultFormatContextName, Format() ); } ImagePrimitivePtr result = new ImagePrimitive( newDataWindow, format.getDisplayWindow() ); ConstCompoundObjectPtr metadata = metadataPlug()->getValue(); compoundObjectToCompoundData( metadata.get(), result->blindData() ); ConstStringVectorDataPtr channelNamesData = channelNamesPlug()->getValue(); const vector<string> &channelNames = channelNamesData->readable(); vector<float *> imageChannelData; for( vector<string>::const_iterator it = channelNames.begin(), eIt = channelNames.end(); it!=eIt; it++ ) { FloatVectorDataPtr cd = new FloatVectorData; vector<float> &c = cd->writable(); c.resize( result->variableSize( PrimitiveVariable::Vertex ), 0.0f ); result->variables[*it] = PrimitiveVariable( PrimitiveVariable::Vertex, cd ); imageChannelData.push_back( &(c[0]) ); } parallel_for( blocked_range3d<size_t>( 0, imageChannelData.size(), 1, 0, dataWindow.size().x+1, tileSize(), 0, dataWindow.size().y+1, tileSize() ), GafferImage::Detail::CopyTiles( imageChannelData, channelNames, channelDataPlug(), dataWindow, Context::current(), tileSize()) ); return result; }
bool outputLight( const ScenePlug *scene, const ScenePlug::ScenePath &path, IECore::Renderer *renderer ) { IECore::ConstLightPtr constLight = runTimeCast<const IECore::Light>( scene->object( path ) ); if( !constLight ) { return false; } if( !visible( scene, path ) ) { /// \todo Since both visible() and fullAttributes() perform similar work, /// we may want to combine them into one query if we see this function /// being a significant fraction of render time. Maybe something like /// `fullAttributes( returnNullIfInvisible = true )`? It probably also /// makes sense to migrate all the convenience functions from ScenePlug /// into SceneAlgo. return false; } ConstCompoundObjectPtr attributes = scene->fullAttributes( path ); const M44f transform = scene->fullTransform( path ); std::string lightHandle; ScenePlug::pathToString( path, lightHandle ); LightPtr light = constLight->copy(); light->setHandle( lightHandle ); { AttributeBlock attributeBlock( renderer ); renderer->setAttribute( "name", new StringData( lightHandle ) ); outputAttributes( attributes.get(), renderer ); renderer->concatTransform( transform ); light->render( renderer ); } renderer->illuminate( lightHandle, true ); return true; }
IECore::CameraPtr GafferScene::camera( const ScenePlug *scene, const IECore::CompoundObject *globals ) { ConstCompoundObjectPtr computedGlobals; if( !globals ) { computedGlobals = scene->globalsPlug()->getValue(); globals = computedGlobals.get(); } if( const StringData *cameraPathData = globals->member<StringData>( "option:render:camera" ) ) { ScenePlug::ScenePath cameraPath; ScenePlug::stringToPath( cameraPathData->readable(), cameraPath ); return camera( scene, cameraPath, globals ); } else { CameraPtr defaultCamera = new IECore::Camera(); applyCameraGlobals( defaultCamera.get(), globals ); return defaultCamera; } }
IECore::ImagePrimitivePtr ImagePlug::image() const { Format format = formatPlug()->getValue(); Box2i dataWindow = dataWindowPlug()->getValue(); Box2i newDataWindow( Imath::V2i(0) ); if( dataWindow.isEmpty() ) { dataWindow = Box2i( Imath::V2i(0) ); } else { newDataWindow = format.yDownToFormatSpace( dataWindow ); } ImagePrimitivePtr result = new ImagePrimitive( newDataWindow, format.getDisplayWindow() ); ConstCompoundObjectPtr metadata = metadataPlug()->getValue(); compoundObjectToCompoundData( metadata.get(), result->blindData() ); ConstStringVectorDataPtr channelNamesData = channelNamesPlug()->getValue(); const vector<string> &channelNames = channelNamesData->readable(); vector<float *> imageChannelData; for( vector<string>::const_iterator it = channelNames.begin(), eIt = channelNames.end(); it!=eIt; it++ ) { FloatVectorDataPtr cd = new FloatVectorData; vector<float> &c = cd->writable(); c.resize( result->variableSize( PrimitiveVariable::Vertex ), 0.0f ); result->variables[*it] = PrimitiveVariable( PrimitiveVariable::Vertex, cd ); imageChannelData.push_back( &(c[0]) ); } parallel_for( blocked_range2d<size_t>( 0, dataWindow.size().x+1, tileSize(), 0, dataWindow.size().y+1, tileSize() ), GafferImage::Detail::CopyTiles( imageChannelData, channelNames, channelDataPlug(), dataWindow, Context::current(), tileSize()) ); return result; }
void InteractiveRender::update() { Context::Scope scopedContext( m_context.get() ); const State requiredState = (State)statePlug()->getValue(); ConstScenePlugPtr requiredScene = inPlug()->getInput<ScenePlug>(); // Stop the current render if it's not what we want, // and early-out if we don't want another one. if( !requiredScene || requiredScene != m_scene || requiredState == Stopped ) { stop(); if( !requiredScene || requiredState == Stopped ) { return; } } // no point doing an update if the scene's empty if( inPlug()->childNames( ScenePlug::ScenePath() )->readable().empty() ) { stop(); return; } // If we've got this far, we know we want to be running or paused. // Start a render if we don't have one. if( !m_renderer ) { m_renderer = createRenderer(); m_renderer->setOption( "editable", new BoolData( true ) ); ConstCompoundObjectPtr globals = inPlug()->globalsPlug()->getValue(); outputOptions( globals.get(), m_renderer.get() ); outputOutputs( globals.get(), m_renderer.get() ); outputCameras( inPlug(), globals.get(), m_renderer.get() ); outputClippingPlanes( inPlug(), globals.get(), m_renderer.get() ); { WorldBlock world( m_renderer ); outputGlobalAttributes( globals.get(), m_renderer.get() ); outputCoordinateSystems( inPlug(), globals.get(), m_renderer.get() ); outputLightsInternal( globals.get(), /* editing = */ false ); // build the scene graph structure in parallel: m_sceneGraph.reset( new SceneGraph ); SceneGraphBuildTask *task = new( tbb::task::allocate_root() ) SceneGraphBuildTask( inPlug(), m_context.get(), m_sceneGraph.get(), ScenePlug::ScenePath() ); tbb::task::spawn_root_and_wait( *task ); // output the scene for the first time: outputScene( false ); } m_scene = requiredScene; m_state = Running; m_lightsDirty = m_attributesDirty = m_camerasDirty = false; } // Make sure the paused/running state is as we want. if( requiredState != m_state ) { if( requiredState == Paused ) { m_renderer->editBegin( "suspendrendering", CompoundDataMap() ); } else { m_renderer->editEnd(); } m_state = requiredState; } // If we're not paused, then send any edits we need. if( m_state == Running ) { EditBlock edit( m_renderer.get(), "suspendrendering", CompoundDataMap() ); updateLights(); updateAttributes(); updateCameras(); updateCoordinateSystems(); } }
void InteractiveRender::update() { Context::Scope scopedContext( m_context.get() ); const State requiredState = (State)statePlug()->getValue(); ConstScenePlugPtr requiredScene = inPlug()->getInput<ScenePlug>(); // Stop the current render if it's not what we want, // and early-out if we don't want another one. if( !requiredScene || requiredScene != m_scene || requiredState == Stopped ) { // stop the current render m_renderer = NULL; m_scene = NULL; m_state = Stopped; m_lightHandles.clear(); m_shadersDirty = m_lightsDirty = m_cameraDirty = true; if( !requiredScene || requiredState == Stopped ) { return; } } // If we've got this far, we know we want to be running or paused. // Start a render if we don't have one. if( !m_renderer ) { m_renderer = createRenderer(); m_renderer->setOption( "editable", new BoolData( true ) ); ConstCompoundObjectPtr globals = inPlug()->globalsPlug()->getValue(); outputOptions( globals.get(), m_renderer.get() ); outputOutputs( globals.get(), m_renderer.get() ); outputCamera( inPlug(), globals.get(), m_renderer.get() ); { WorldBlock world( m_renderer ); outputGlobalAttributes( globals.get(), m_renderer.get() ); outputCoordinateSystems( inPlug(), globals.get(), m_renderer.get() ); outputLightsInternal( globals.get(), /* editing = */ false ); SceneProceduralPtr proc = new SceneProcedural( inPlug(), Context::current() ); m_renderer->procedural( proc ); } m_scene = requiredScene; m_state = Running; m_lightsDirty = m_shadersDirty = m_cameraDirty = false; } // Make sure the paused/running state is as we want. if( requiredState != m_state ) { if( requiredState == Paused ) { m_renderer->editBegin( "suspendrendering", CompoundDataMap() ); } else { m_renderer->editEnd(); } m_state = requiredState; } // If we're not paused, then send any edits we need. if( m_state == Running ) { updateLights(); updateShaders(); updateCamera(); updateCoordinateSystems(); } }