Esempio n. 1
0
void InputBinder::bind(const Scene& scene)
{
    try
    {
        // Build the symbol table of the scene.
        SymbolTable scene_symbols;
        build_scene_symbol_table(scene, scene_symbols);

        // Bind all inputs of all entities in the scene.
        bind_scene_entities_inputs(scene, scene_symbols);

        // Bind all inputs of all entities in all assemblies.
        for (const_each<AssemblyContainer> i = scene.assemblies(); i; ++i)
        {
            assert(m_assembly_info.empty());
            bind_assembly_entities_inputs(scene, scene_symbols, *i);
        }
    }
    catch (const ExceptionUnknownEntity& e)
    {
        RENDERER_LOG_ERROR(
            "while binding inputs of \"%s\": could not locate entity \"%s\".",
            e.get_context_path().c_str(),
            e.string());
        ++m_error_count;
    }
}
Esempio n. 2
0
void InputBinder::bind(const Scene& scene)
{
    // Build the symbol table of the scene.
    SymbolTable scene_symbols;
    build_scene_symbol_table(
        scene,
        scene_symbols);

    // Bind all inputs of all entities in the scene.
    bind_scene_entities_inputs(
        scene,
        scene_symbols);

    // Bind inputs of all entities in assemblies.
    for (const_each<AssemblyContainer> i = scene.assemblies(); i; ++i)
    {
        // Retrieve the assembly.
        const Assembly& assembly = *i;

        // Build the symbol table of the assembly.
        SymbolTable assembly_symbols;
        build_assembly_symbol_table(
            assembly,
            assembly_symbols);

        // Bind all inputs of all entities in the assembly.
        bind_assembly_entities_inputs(
            scene,
            scene_symbols,
            assembly,
            assembly_symbols);
    }
}
Esempio n. 3
0
    // Render a frame until completed or aborted and handle reinitialization events.
    MasterRenderer::RenderingResult::Status do_render()
    {
        while (true)
        {
            m_renderer_controller->on_rendering_begin();

            // Construct an abort switch that will allow to abort initialization.
            RendererControllerAbortSwitch abort_switch(*m_renderer_controller);

            // Expand procedural assemblies before scene entities inputs are bound.
            if (!m_project.get_scene()->expand_procedural_assemblies(m_project, &abort_switch))
            {
                m_renderer_controller->on_rendering_abort();
                return RenderingResult::Aborted;
            }

            // Bind scene entities inputs.
            if (!bind_scene_entities_inputs())
            {
                m_renderer_controller->on_rendering_abort();
                return RenderingResult::Aborted;
            }

            const IRendererController::Status status = initialize_and_render_frame();

            switch (status)
            {
              case IRendererController::TerminateRendering:
                m_renderer_controller->on_rendering_success();
                return RenderingResult::Succeeded;

              case IRendererController::AbortRendering:
                m_renderer_controller->on_rendering_abort();
                return RenderingResult::Aborted;

              case IRendererController::ReinitializeRendering:
                break;

              assert_otherwise;
            }
        }
    }
Esempio n. 4
0
IRendererController::Status MasterRenderer::initialize_and_render_frame_sequence()
{
    assert(m_project.get_scene());
    assert(m_project.get_frame());

    // Reset the abort switch.
    if (m_abort_switch)
        m_abort_switch->clear();

#ifdef WITH_OSL

    // Create the error handler.
    OIIOErrorHandler error_handler;

    // While debugging, we want all possible outputs.
#ifndef NDEBUG
    error_handler.verbosity(OIIO::ErrorHandler::VERBOSE);
#endif

    const size_t texture_cache_size =
        m_params.get_optional<size_t>("texture_cache_size",  256 * 1024 * 1024);

    // If the texture cache size changes, we have to recreate the texture system.
    if (texture_cache_size != m_texture_cache_size)
    {
        m_texture_cache_size = texture_cache_size;
        m_texture_system.reset();
    }

    // Create the OIIO texture system, if needed.
    if (!m_texture_system)
    {
        m_texture_system.reset(
            OIIO::TextureSystem::create(false),
            bind(&OIIO::TextureSystem::destroy, _1));
    }

    // Set the texture system mem limit.
    m_texture_system->attribute("max_memory_MB", static_cast<float>(m_texture_cache_size / 1024));

    std::string search_paths;

    // Skip search paths for builtin projects.
    if (m_project.search_paths().has_root_path())
    {
        // Setup texture / shader search paths.
        // In OIIO / OSL, the path priorities are the opposite of appleseed,
        // so we copy the paths in reverse order.

        const filesystem::path root_path = m_project.search_paths().get_root_path();

        if (!m_project.search_paths().empty())
        {
            for (size_t i = 0, e = m_project.search_paths().size(); i != e; ++i)
            {
                filesystem::path p(m_project.search_paths()[e - 1 - i]);

                if (p.is_relative())
                   p = root_path / p;

                search_paths.append(p.string());
                search_paths.append(";");
            }
        }

        search_paths.append(root_path.string());
    }

    if (!search_paths.empty())
        m_texture_system->attribute("searchpath", search_paths);

    // TODO: set other texture system options here.

    // Create our renderer services.
    RendererServices services(m_project, *m_texture_system);

    // Create our OSL shading system.
    boost::shared_ptr<OSL::ShadingSystem> shading_system(
        OSL::ShadingSystem::create(
            &services,
            m_texture_system.get(),
            &error_handler),
            bind(&destroy_osl_shading_system, _1, m_texture_system.get()));

    if (!search_paths.empty())
        shading_system->attribute("searchpath:shader", search_paths);

    shading_system->attribute("lockgeom", 1);
    shading_system->attribute("colorspace", "Linear");
    shading_system->attribute("commonspace", "world");

    // This array needs to be kept in sync with the ShadingRay::Type enumeration.
    static const char* ray_type_labels[] =
    {
        "camera",
        "light",
        "shadow",
        "probe",
        "diffuse",
        "glossy",
        "specular"
    };

    shading_system->attribute(
        "raytypes",
        OSL::TypeDesc(
            OSL::TypeDesc::STRING,
            sizeof(ray_type_labels) / sizeof(ray_type_labels[0])),
        ray_type_labels);

#ifndef NDEBUG
    // While debugging, we want all possible outputs.
    shading_system->attribute("debug", 1);
    shading_system->attribute("statistics:level", 1);
    shading_system->attribute("compile_report", 1);
    shading_system->attribute("countlayerexecs", 1);
    shading_system->attribute("clearmemory", 1);
#endif

    register_closures(*shading_system);

#endif  // WITH_OSL

    // We start by binding entities inputs. This must be done before creating/updating the trace context.
    if (!bind_scene_entities_inputs())
        return IRendererController::AbortRendering;

    m_project.create_aov_images();
    m_project.update_trace_context();

    const Scene& scene = *m_project.get_scene();

    Frame& frame = *m_project.get_frame();
    frame.print_settings();

    const TraceContext& trace_context = m_project.get_trace_context();

    // Create the texture store.
    TextureStore texture_store(scene, m_params.child("texture_store"));

    // Create the light sampler.
    LightSampler light_sampler(scene, m_params.child("light_sampler"));

    // Create the shading engine.
    ShadingEngine shading_engine(m_params.child("shading_engine"));

    //
    // Create a lighting engine factory.
    //

    auto_ptr<IPassCallback> pass_callback;
    auto_ptr<ILightingEngineFactory> lighting_engine_factory;
    {
        const string value = m_params.get_required<string>("lighting_engine", "pt");

        if (value == "drt")
        {
            lighting_engine_factory.reset(
                new DRTLightingEngineFactory(
                    light_sampler,
                    m_params.child("drt")));    // todo: change to "drt_lighting_engine" -- or?
        }
        else if (value == "pt")
        {
            lighting_engine_factory.reset(
                new PTLightingEngineFactory(
                    light_sampler,
                    m_params.child("pt")));     // todo: change to "pt_lighting_engine" -- or?
        }
        else if (value == "sppm")
        {
            const SPPMParameters params(m_params.child("sppm"));

            SPPMPassCallback* sppm_pass_callback =
                new SPPMPassCallback(
                    scene,
                    light_sampler,
                    trace_context,
                    texture_store,
#ifdef WITH_OSL
                    *shading_system,
#endif
                    params);
            pass_callback.reset(sppm_pass_callback);

            lighting_engine_factory.reset(
                new SPPMLightingEngineFactory(
                    *sppm_pass_callback,
                    light_sampler,
                    params));
        }
        else
        {
            RENDERER_LOG_ERROR(
                "invalid value for \"lighting_engine\" parameter: \"%s\".",
                value.c_str());

            return IRendererController::AbortRendering;
        }
    }

    //
    // Create a sample renderer factory.
    //

    auto_ptr<ISampleRendererFactory> sample_renderer_factory;
    {
        const string value = m_params.get_required<string>("sample_renderer", "generic");

        if (value == "generic")
        {
            sample_renderer_factory.reset(
                new GenericSampleRendererFactory(
                    scene,
                    frame,
                    trace_context,
                    texture_store,
                    lighting_engine_factory.get(),
                    shading_engine,
#ifdef WITH_OSL
                    *shading_system,
#endif
                    m_params.child("generic_sample_renderer")));
        }
        else if (value == "blank")
        {
            sample_renderer_factory.reset(new BlankSampleRendererFactory());
        }
        else if (value == "debug")
        {
            sample_renderer_factory.reset(new DebugSampleRendererFactory());
        }
        else
        {
            RENDERER_LOG_ERROR(
                "invalid value for \"sample_renderer\" parameter: \"%s\".",
                value.c_str());

            return IRendererController::AbortRendering;
        }
    }

    //
    // Create a sample generator factory.
    //

    auto_ptr<ISampleGeneratorFactory> sample_generator_factory;
    {
        const string value = m_params.get_optional<string>("sample_generator", "");

        if (value == "generic")
        {
            sample_generator_factory.reset(
                new GenericSampleGeneratorFactory(
                    frame,
                    sample_renderer_factory.get()));
        }
        else if (value == "lighttracing")
        {
            sample_generator_factory.reset(
                new LightTracingSampleGeneratorFactory(
                    scene,
                    frame,
                    trace_context,
                    texture_store,
                    light_sampler,
#ifdef WITH_OSL
                    *shading_system,
#endif
                    m_params.child("lighttracing_sample_generator")));
        }
        else if (!value.empty())
        {
            RENDERER_LOG_ERROR(
                "invalid value for \"sample_generator\" parameter: \"%s\".",
                value.c_str());

            return IRendererController::AbortRendering;
        }
    }

    //
    // Create a pixel renderer factory.
    //

    auto_ptr<IPixelRendererFactory> pixel_renderer_factory;
    {
        const string value = m_params.get_optional<string>("pixel_renderer", "");

        if (value == "uniform")
        {
            pixel_renderer_factory.reset(
                new UniformPixelRendererFactory(
                    sample_renderer_factory.get(),
                    m_params.child("uniform_pixel_renderer")));
        }
        else if (value == "adaptive")
        {
            pixel_renderer_factory.reset(
                new AdaptivePixelRendererFactory(
                    frame,
                    sample_renderer_factory.get(),
                    m_params.child("adaptive_pixel_renderer")));
        }
        else if (!value.empty())
        {
            RENDERER_LOG_ERROR(
                "invalid value for \"pixel_renderer\" parameter: \"%s\".",
                value.c_str());

            return IRendererController::AbortRendering;
        }
    }

    //
    // Create a shading result framebuffer factory.
    //

    auto_ptr<IShadingResultFrameBufferFactory> shading_result_framebuffer_factory;
    {
        const string value =
            m_params.get_optional<string>("shading_result_framebuffer", "ephemeral");

        if (value == "ephemeral")
        {
            shading_result_framebuffer_factory.reset(
                new EphemeralShadingResultFrameBufferFactory());
        }
        else if (value == "permanent")
        {
            shading_result_framebuffer_factory.reset(
                new PermanentShadingResultFrameBufferFactory(frame));
        }
        else if (!value.empty())
        {
            RENDERER_LOG_ERROR(
                "invalid value for \"shading_result_framebuffer\" parameter: \"%s\".",
                value.c_str());

            return IRendererController::AbortRendering;
        }
    }

    //
    // Create a tile renderer factory.
    //

    auto_ptr<ITileRendererFactory> tile_renderer_factory;
    {
        const string value = m_params.get_optional<string>("tile_renderer", "");

        if (value == "generic")
        {
            tile_renderer_factory.reset(
                new GenericTileRendererFactory(
                    frame,
                    pixel_renderer_factory.get(),
                    shading_result_framebuffer_factory.get(),
                    m_params.child("generic_tile_renderer")));
        }
        else if (value == "blank")
        {
            tile_renderer_factory.reset(new BlankTileRendererFactory());
        }
        else if (value == "debug")
        {
            tile_renderer_factory.reset(new DebugTileRendererFactory());
        }
        else if (!value.empty())
        {
            RENDERER_LOG_ERROR(
                "invalid value for \"tile_renderer\" parameter: \"%s\".",
                value.c_str());

            return IRendererController::AbortRendering;
        }
    }

    //
    // Create a frame renderer.
    //

    auto_release_ptr<IFrameRenderer> frame_renderer;
    {
        const string value = m_params.get_required<string>("frame_renderer", "generic");

        if (value == "generic")
        {
            ParamArray params = m_params.child("generic_frame_renderer");
            copy_param(params, m_params, "rendering_threads");

            frame_renderer.reset(
                GenericFrameRendererFactory::create(
                    frame,
                    tile_renderer_factory.get(),
                    m_tile_callback_factory,
                    pass_callback.get(),
                    params));
        }
        else if (value == "progressive")
        {
            ParamArray params = m_params.child("progressive_frame_renderer");
            copy_param(params, m_params, "rendering_threads");

            frame_renderer.reset(
                ProgressiveFrameRendererFactory::create(
                    m_project,
                    sample_generator_factory.get(),
                    m_tile_callback_factory,
                    params));
        }
        else
        {
            RENDERER_LOG_ERROR(
                "invalid value for \"frame_renderer\" parameter: \"%s\".",
                value.c_str());

            return IRendererController::AbortRendering;
        }
    }

    // Execute the main rendering loop.
    const IRendererController::Status status =
        render_frame_sequence(
            frame_renderer.get()
#ifdef WITH_OSL
            , *shading_system
#endif
            );

    // Print texture store performance statistics.
    RENDERER_LOG_DEBUG("%s", texture_store.get_statistics().to_string().c_str());

    return status;
}