示例#1
0
bool Frame::write_image(
    const char*             file_path,
    const Image&            image,
    const ImageAttributes&  image_attributes) const
{
    assert(file_path);

    Image final_image(image);
    transform_to_output_color_space(final_image);

    Stopwatch<DefaultWallclockTimer> stopwatch;
    stopwatch.start();

    try
    {
        try
        {
            GenericImageFileWriter writer;
            writer.write(file_path, final_image, image_attributes);
        }
        catch (const ExceptionUnsupportedFileFormat&)
        {
            const string extension = lower_case(filesystem::path(file_path).extension());

            RENDERER_LOG_ERROR(
                "file format '%s' not supported, writing the image in OpenEXR format "
                "(but keeping the filename unmodified).",
                extension.c_str());

            EXRImageFileWriter writer;
            writer.write(file_path, final_image, image_attributes);
        }
    }
    catch (const ExceptionIOError&)
    {
        RENDERER_LOG_ERROR(
            "failed to write image file %s: i/o error.",
            file_path);

        return false;
    }
    catch (const Exception& e)
    {
        RENDERER_LOG_ERROR(
            "failed to write image file %s: %s.",
            file_path,
            e.what());

        return false;
    }

    stopwatch.measure();

    RENDERER_LOG_INFO(
        "wrote image file %s in %s.",
        file_path,
        pretty_time(stopwatch.get_seconds()).c_str());

    return true;
}
示例#2
0
void InputBinder::bind_scene_entity_inputs(
    const Scene&                    scene,
    const SymbolTable&              scene_symbols,
    const char*                     entity_type,
    ConnectableEntity&              entity)
{
    const string entity_path = entity.get_path();
    const ParamArray& entity_params = entity.get_parameters();

    for (each<InputArray> i = entity.get_inputs(); i; ++i)
    {
        InputArray::iterator& input = *i;
        string param_value;

        if (entity_params.strings().exist(input.name()))
        {
            // A value is assigned to this input, retrieve it.
            param_value = entity_params.get<string>(input.name());
        }
        else if (input.type() == InputTypeOptional)
        {
            // This input is optional, use its default value.
            param_value = input.default_value();
            if (param_value.empty())
                continue;
        }
        else
        {
            // This input is required but has no value, this is an error.
            RENDERER_LOG_ERROR(
                "while defining %s \"%s\": required parameter \"%s\" missing.",
                entity_type,
                entity_path.c_str(),
                input.name());
            ++m_error_count;
            continue;
        }

        if (try_bind_scene_entity_to_input(
                scene,
                scene_symbols,
                entity_type,
                entity_path.c_str(),
                param_value.c_str(),
                input))
            continue;

        if (try_bind_scalar_to_input(param_value, input))
            continue;

        RENDERER_LOG_ERROR(
            "while defining %s \"%s\": cannot bind \"%s\" to parameter \"%s\".",
            entity_type,
            entity_path.c_str(),
            param_value.c_str(),
            input.name());

        ++m_error_count;
    }
}
示例#3
0
bool MasterRenderer::render()
{
    try
    {
        do_render();
        return true;
    }
    catch (const bad_alloc&)
    {
        m_renderer_controller->on_rendering_abort();
        RENDERER_LOG_ERROR("rendering failed (ran out of memory).");
        return false;
    }
#ifdef NDEBUG
    catch (const std::exception& e)
    {
        m_renderer_controller->on_rendering_abort();
        RENDERER_LOG_ERROR("rendering failed (%s).", e.what());
        return false;
    }
    catch (...)
    {
        m_renderer_controller->on_rendering_abort();
        RENDERER_LOG_ERROR("rendering failed (unknown exception).");
        return false;
    }
#endif
}
示例#4
0
bool Material::on_frame_begin(
    const Project&      project,
    const Assembly&     assembly)
{
    m_surface_shader = get_uncached_surface_shader();
    m_bsdf = get_uncached_bsdf();
    m_edf = get_uncached_edf();
    m_alpha_map = get_uncached_alpha_map();

    const Source* displacement_source = m_inputs.source("displacement_map");

    if (displacement_source)
    {
        if (dynamic_cast<const TextureSource*>(displacement_source) == 0)
        {
            RENDERER_LOG_ERROR(
                "while defining material \"%s\": a texture instance must be bound "
                "to the \"displacement_map\" input; disabling displacement map for this material.",
                get_name());
        }
        else
        {
            const TextureSource* displacement_map = static_cast<const TextureSource*>(displacement_source);
            const Texture& texture = displacement_map->get_texture_instance().get_texture();

            if (texture.get_color_space() != ColorSpaceLinearRGB)
            {
                RENDERER_LOG_WARNING(
                    "while defining material \"%s\": color space for displacement map \"%s\" "
                    "should be \"%s\" but is \"%s\" instead; expect artifacts and/or slowdowns.",
                    get_name(),
                    texture.get_name(),
                    color_space_name(ColorSpaceLinearRGB),
                    color_space_name(texture.get_color_space()));
            }

            // Retrieve the displacement method and create the normal modifier.
            const string displacement_method =
                m_params.get_required<string>("displacement_method", "bump");
            if (displacement_method == "bump")
            {
                const double amplitude = m_params.get_optional<double>("bump_amplitude", 1.0);
                m_normal_modifier = new BumpMappingModifier(displacement_map, 2.0, amplitude);
            }
            else if (displacement_method == "normal")
                m_normal_modifier = new NormalMappingModifier(displacement_map);
            else
            {
                RENDERER_LOG_ERROR(
                    "while defining material \"%s\": invalid value \"%s\" for parameter "
                    "\"displacement_method\"; disabling displacement map for this material.",
                    get_name(),
                    displacement_method.c_str());
            }
        }
    }

    return true;
}
示例#5
0
void ColorEntity::extract_parameters()
{
    // Retrieve the color space.
    const ColorSpace DefaultColorSpace = ColorSpaceSRGB;
    const char* DefaultColorSpaceName = color_space_name(DefaultColorSpace);
    const string color_space = m_params.get_required<string>("color_space", DefaultColorSpaceName);
    if (color_space == "linear_rgb")
        impl->m_color_space = ColorSpaceLinearRGB;
    else if (color_space == "srgb")
        impl->m_color_space = ColorSpaceSRGB;
    else if (color_space == "ciexyz")
        impl->m_color_space = ColorSpaceCIEXYZ;
    else if (color_space == "spectral")
        impl->m_color_space = ColorSpaceSpectral;
    else
    {
        RENDERER_LOG_ERROR(
            "invalid value \"%s\" for parameter \"color_space\", "
            "using default value \"%s\".",
            color_space.c_str(),
            DefaultColorSpaceName);
        impl->m_color_space = DefaultColorSpace;
    }

    // For the spectral color space, retrieve the wavelength range.
    if (impl->m_color_space == ColorSpaceSpectral)
    {
        const Vector2f DefaultWavelengthRange(LowWavelength, HighWavelength);
        impl->m_wavelength_range =
            m_params.get_required<Vector2f>(
                "wavelength_range",
                DefaultWavelengthRange);

        if (impl->m_wavelength_range[0] < 0.0 ||
            impl->m_wavelength_range[1] < 0.0 ||
            impl->m_wavelength_range[0] > impl->m_wavelength_range[1])
        {
            RENDERER_LOG_ERROR(
                "invalid value \"%f %f\" for parameter \"%s\", "
                "using default value \"%f %f\".",
                impl->m_wavelength_range[0],
                impl->m_wavelength_range[1],
                "wavelength_range",
                DefaultWavelengthRange[0],
                DefaultWavelengthRange[1]);

            impl->m_wavelength_range = DefaultWavelengthRange;
        }
    }
    else
    {
        impl->m_wavelength_range[0] =
        impl->m_wavelength_range[1] = 0.0f;
    }

    // Retrieve multiplier.
    impl->m_multiplier = m_params.get_optional<float>("multiplier", 1.0f);
}
bool RendererComponents::create_frame_renderer_factory()
{
    const string name = m_params.get_required<string>("frame_renderer", "generic");

    if (name.empty())
    {
        return true;
    }
    else if (name == "generic")
    {
        if (m_tile_renderer_factory.get() == 0)
        {
            RENDERER_LOG_ERROR("cannot use the generic frame renderer without a tile renderer.");
            return false;
        }

        m_frame_renderer.reset(
            GenericFrameRendererFactory::create(
                m_frame,
                m_tile_renderer_factory.get(),
                m_tile_callback_factory,
                m_pass_callback.get(),
                get_child_and_inherit_globals(m_params, "generic_frame_renderer")));
        return true;
    }
    else if (name == "progressive")
    {
        if (m_sample_generator_factory.get() == 0)
        {
            RENDERER_LOG_ERROR("cannot use the progressive frame renderer without a sample generator.");
            return false;
        }

        m_frame_renderer.reset(
            ProgressiveFrameRendererFactory::create(
                m_project,
                m_sample_generator_factory.get(),
                m_tile_callback_factory,
                get_child_and_inherit_globals(m_params, "progressive_frame_renderer")));
        return true;
    }
    else
    {
        RENDERER_LOG_ERROR(
            "invalid value for \"frame_renderer\" parameter: \"%s\".",
            name.c_str());
        return false;
    }
}
bool RendererComponents::create_sample_generator_factory()
{
    const string name = m_params.get_optional<string>("sample_generator", "");

    if (name.empty())
    {
        return true;
    }
    else if (name == "generic")
    {
        if (m_sample_renderer_factory.get() == 0)
        {
            RENDERER_LOG_ERROR("cannot use the generic sample generator without a sample renderer.");
            return false;
        }

        m_sample_generator_factory.reset(
            new GenericSampleGeneratorFactory(
                m_frame,
                m_sample_renderer_factory.get(),
                get_child_and_inherit_globals(m_params, "generic_sample_generator")));
        return true;
    }
    else if (name == "lighttracing")
    {
        m_sample_generator_factory.reset(
            new LightTracingSampleGeneratorFactory(
                m_scene,
                m_frame,
                m_trace_context,
                m_texture_store,
                m_light_sampler,
#ifdef APPLESEED_WITH_OIIO
                m_texture_system,
#endif
#ifdef APPLESEED_WITH_OSL
                m_shading_system,
#endif
                get_child_and_inherit_globals(m_params, "lighttracing_sample_generator")));
        return true;
    }
    else
    {
        RENDERER_LOG_ERROR(
            "invalid value for \"sample_generator\" parameter: \"%s\".",
            name.c_str());
        return false;
    }
}
bool RendererComponents::create_tile_renderer_factory()
{
    const string name = m_params.get_optional<string>("tile_renderer", "");

    if (name.empty())
    {
        return true;
    }
    else if (name == "generic")
    {
        if (m_pixel_renderer_factory.get() == 0)
        {
            RENDERER_LOG_ERROR("cannot use the generic tile renderer without a pixel renderer.");
            return false;
        }

        if (m_shading_result_framebuffer_factory.get() == 0)
        {
            RENDERER_LOG_ERROR("cannot use the generic tile renderer without a shading result framebuffer.");
            return false;
        }

        m_tile_renderer_factory.reset(
            new GenericTileRendererFactory(
                m_frame,
                m_pixel_renderer_factory.get(),
                m_shading_result_framebuffer_factory.get(),
                get_child_and_inherit_globals(m_params, "generic_tile_renderer")));
        return true;
    }
    else if (name == "blank")
    {
        m_tile_renderer_factory.reset(new BlankTileRendererFactory());
        return true;
    }
    else if (name == "debug")
    {
        m_tile_renderer_factory.reset(new DebugTileRendererFactory());
        return true;
    }
    else
    {
        RENDERER_LOG_ERROR(
            "invalid value for \"tile_renderer\" parameter: \"%s\".",
            name.c_str());
        return false;
    }
}
示例#9
0
void OIIOErrorHandler::operator()(int errcode, const std::string& msg)
{
    switch (errcode)
    {
      case EH_WARNING:
        RENDERER_LOG_WARNING("%s", msg.c_str());
        break;

      case EH_ERROR:
        RENDERER_LOG_ERROR("%s", msg.c_str());
        break;

      case EH_SEVERE:
        RENDERER_LOG_FATAL("%s", msg.c_str());
        break;

      case EH_DEBUG:
        RENDERER_LOG_DEBUG("%s", msg.c_str());
        break;

      default:
        RENDERER_LOG_INFO("%s", msg.c_str());
        break;
    }
}
示例#10
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;
    }
}
示例#11
0
void InputBinder::build_scene_symbol_table(
    const Scene&                    scene,
    SymbolTable&                    symbols)
{
    try
    {
        if (scene.get_camera())
            symbols.insert(scene.get_camera()->get_name(), SymbolTable::SymbolCamera);

        insert_entities(symbols, scene.colors(), SymbolTable::SymbolColor);
        insert_entities(symbols, scene.textures(), SymbolTable::SymbolTexture);
        insert_entities(symbols, scene.texture_instances(), SymbolTable::SymbolTextureInstance);
        insert_entities(symbols, scene.environment_edfs(), SymbolTable::SymbolEnvironmentEDF);
        insert_entities(symbols, scene.environment_shaders(), SymbolTable::SymbolEnvironmentShader);

#ifdef APPLESEED_WITH_OSL
        insert_entities(symbols, scene.shader_groups(), SymbolTable::SymbolShaderGroup);
#endif
        if (scene.get_environment())
            symbols.insert(scene.get_environment()->get_name(), SymbolTable::SymbolEnvironment);

        insert_entities(symbols, scene.assemblies(), SymbolTable::SymbolAssembly);
        insert_entities(symbols, scene.assembly_instances(), SymbolTable::SymbolAssemblyInstance);
    }
    catch (const SymbolTable::ExceptionDuplicateSymbol& e)
    {
        RENDERER_LOG_ERROR("duplicate entity \"%s\".", e.string());
        ++m_error_count;
    }
}
示例#12
0
bool MeshObjectWriter::write(
    const MeshObject&   object,
    const char*         object_name,
    const char*         filename)
{
    assert(filename);

    Stopwatch<DefaultWallclockTimer> stopwatch;
    stopwatch.start();

    try
    {
        GenericMeshFileWriter writer(filename);
        MeshObjectWalker walker(object, object_name);
        writer.write(walker);
    }
    catch (const exception& e)
    {
        RENDERER_LOG_ERROR(
            "failed to write mesh file %s: %s.",
            filename,
            e.what());
        return false;
    }

    stopwatch.measure();

    RENDERER_LOG_INFO(
        "wrote mesh file %s in %s.",
        filename,
        pretty_time(stopwatch.get_seconds()).c_str());

    return true;
}
示例#13
0
bool RendererComponents::create_shading_result_framebuffer_factory()
{
    const string name = m_params.get_optional<string>("shading_result_framebuffer", "ephemeral");

    if (name.empty())
    {
        return true;
    }
    else if (name == "ephemeral")
    {
        m_shading_result_framebuffer_factory.reset(
            new EphemeralShadingResultFrameBufferFactory());
        return true;
    }
    else if (name == "permanent")
    {
        m_shading_result_framebuffer_factory.reset(
            new PermanentShadingResultFrameBufferFactory(m_frame));
        return true;
    }
    else
    {
        RENDERER_LOG_ERROR(
            "invalid value for \"shading_result_framebuffer\" parameter: \"%s\".",
            name.c_str());
        return false;
    }
}
示例#14
0
void InputBinder::build_assembly_symbol_table(
    const Assembly&                 assembly,
    SymbolTable&                    symbols)
{
    try
    {
        insert_entities(symbols, assembly.colors(), SymbolTable::SymbolColor);
        insert_entities(symbols, assembly.textures(), SymbolTable::SymbolTexture);
        insert_entities(symbols, assembly.texture_instances(), SymbolTable::SymbolTextureInstance);
        insert_entities(symbols, assembly.bsdfs(), SymbolTable::SymbolBSDF);
        insert_entities(symbols, assembly.bssrdfs(), SymbolTable::SymbolBSSRDF);
        insert_entities(symbols, assembly.edfs(), SymbolTable::SymbolEDF);
#ifdef APPLESEED_WITH_OSL
        insert_entities(symbols, assembly.shader_groups(), SymbolTable::SymbolShaderGroup);
#endif
        insert_entities(symbols, assembly.surface_shaders(), SymbolTable::SymbolSurfaceShader);
        insert_entities(symbols, assembly.materials(), SymbolTable::SymbolMaterial);
        insert_entities(symbols, assembly.lights(), SymbolTable::SymbolLight);
        insert_entities(symbols, assembly.objects(), SymbolTable::SymbolObject);
        insert_entities(symbols, assembly.object_instances(), SymbolTable::SymbolObjectInstance);
    }
    catch (const SymbolTable::ExceptionDuplicateSymbol& e)
    {
        RENDERER_LOG_ERROR("duplicate entity \"%s\".", e.string());
        ++m_error_count;
    }
}
示例#15
0
bool RendererComponents::create_lighting_engine_factory()
{
    const string name = m_params.get_required<string>("lighting_engine", "pt");

    if (name.empty())
    {
        return true;
    }
    else if (name == "drt")
    {
        m_lighting_engine_factory.reset(
            new DRTLightingEngineFactory(
                m_light_sampler,
                child_inherit(m_params, "drt")));   // todo: change to "drt_lighting_engine"?
        return true;
    }
    else if (name == "pt")
    {
        m_lighting_engine_factory.reset(
            new PTLightingEngineFactory(
                m_light_sampler,
                child_inherit(m_params, "pt")));    // todo: change to "pt_lighting_engine"?
        return true;
    }
    else if (name == "sppm")
    {
        const SPPMParameters sppm_params(child_inherit(m_params, "sppm"));

        SPPMPassCallback* sppm_pass_callback =
            new SPPMPassCallback(
                m_scene,
                m_light_sampler,
                m_trace_context,
                m_texture_store,
#ifdef APPLESEED_WITH_OIIO
                m_texture_system,
#endif
#ifdef APPLESEED_WITH_OSL
                m_shading_system,
#endif
                sppm_params);

        m_pass_callback.reset(sppm_pass_callback);

        m_lighting_engine_factory.reset(
            new SPPMLightingEngineFactory(
                *sppm_pass_callback,
                m_light_sampler,
                sppm_params));

        return true;
    }
    else
    {
        RENDERER_LOG_ERROR(
            "invalid value for \"lighting_engine\" parameter: \"%s\".",
            name.c_str());
        return false;
    }
}
示例#16
0
void InputBinder::bind_texture_instance_to_input(
    const TextureInstanceContainer& texture_instances,
    const UniqueID                  assembly_uid,
    const char*                     entity_type,
    const char*                     entity_name,
    const char*                     param_value,
    InputArray::iterator&           input)
{
    const TextureInstance* texture_instance = texture_instances.get_by_name(param_value);
    assert(texture_instance);

    try
    {
        input.bind(
            new TextureSource(
                assembly_uid,
                *texture_instance));
    }
    catch (const exception& e)
    {
        RENDERER_LOG_ERROR(
            "while defining %s \"%s\", failed to bind \"%s\" to input \"%s\" (%s).",
            entity_type,
            entity_name,
            param_value,
            input.name(),
            e.what());

        ++m_error_count;
    }
}
auto_release_ptr<MeshObject> create_primitive_mesh(const char* name, const ParamArray& params)
{
    const char* primitive_type = params.get("primitive");

    // Parametric surfaces.

    if (strcmp(primitive_type, "grid") == 0)
        return create_parametric_surface<ParametricGrid>(name, params);

    if (strcmp(primitive_type, "disk") == 0)
        return create_parametric_surface<ParametricDisk>(name, params);

    if (strcmp(primitive_type, "sphere") == 0)
        return create_parametric_surface<ParametricSphere>(name, params);

    if (strcmp(primitive_type, "torus") == 0)
        return create_parametric_surface<ParametricTorus>(name, params);

    // Other, non-parametric primitives.

    if (strcmp(primitive_type, "cube") == 0)
        return create_cube(name, params);

    RENDERER_LOG_ERROR("unknown primitive type: %s", primitive_type);
    return auto_release_ptr<MeshObject>();
}
示例#18
0
bool RendererComponents::create_pixel_renderer_factory()
{
    const string name = m_params.get_optional<string>("pixel_renderer", "");

    if (name.empty())
    {
        return true;
    }
    else if (name == "uniform")
    {
        if (m_sample_renderer_factory.get() == 0)
        {
            RENDERER_LOG_ERROR("cannot use the uniform pixel renderer without a sample renderer.");
            return false;
        }

        ParamArray params = get_child_and_inherit_globals(m_params, "uniform_pixel_renderer");
        copy_param(params, m_params, "passes");
        m_pixel_renderer_factory.reset(
            new UniformPixelRendererFactory(
                m_sample_renderer_factory.get(),
                params));
        return true;
    }
    else if (name == "adaptive")
    {
        if (m_sample_renderer_factory.get() == 0)
        {
            RENDERER_LOG_ERROR("cannot use the adaptive pixel renderer without a sample renderer.");
            return false;
        }

        m_pixel_renderer_factory.reset(
            new AdaptivePixelRendererFactory(
                m_frame,
                m_sample_renderer_factory.get(),
                get_child_and_inherit_globals(m_params, "adaptive_pixel_renderer")));
        return true;
    }
    else
    {
        RENDERER_LOG_ERROR(
            "invalid value for \"pixel_renderer\" parameter: \"%s\".",
            name.c_str());
        return false;
    }
}
示例#19
0
IBasisModifier* Material::create_basis_modifier(const MessageContext& context) const
{
    // Retrieve the source bound to the displacement map input.
    const Source* displacement_source = m_inputs.source("displacement_map");

    // Nothing to do if there is no displacement source.
    if (displacement_source == 0)
        return 0;

    // Only texture instances can be bound to the displacement map input.
    if (dynamic_cast<const TextureSource*>(displacement_source) == 0)
    {
        RENDERER_LOG_ERROR(
            "%s: a texture instance must be bound to the \"displacement_map\" input.",
            context.get());
        return 0;
    }

    // Retrieve the displacement texture.
    const TextureSource* displacement_map = static_cast<const TextureSource*>(displacement_source);
    const Texture& texture = displacement_map->get_texture_instance().get_texture();

    // Print a warning if the displacement texture is not expressed in the linear RGB color space.
    if (texture.get_color_space() != ColorSpaceLinearRGB)
    {
        RENDERER_LOG_WARNING(
            "%s: color space for displacement map \"%s\" "
            "should be \"%s\" but is \"%s\" instead; expect artifacts and/or slowdowns.",
            context.get(),
            texture.get_path().c_str(),
            color_space_name(ColorSpaceLinearRGB),
            color_space_name(texture.get_color_space()));
    }

    // Retrieve the displacement method.
    const string displacement_method =
        m_params.get_required<string>(
            "displacement_method",
            "bump",
            make_vector("bump", "normal"),
            context);

    // Create the basis modifier.
    if (displacement_method == "bump")
    {
        const float offset = m_params.get_optional<float>("bump_offset", 2.0f);
        const float amplitude = m_params.get_optional<float>("bump_amplitude", 1.0f);
        return new BumpMappingModifier(displacement_map, offset, amplitude);
    }
    else
    {
        const NormalMappingModifier::UpVector up_vector =
            m_params.get_optional<string>("normal_map_up", "z", make_vector("y", "z"), context) == "y"
                ? NormalMappingModifier::UpVectorY
                : NormalMappingModifier::UpVectorZ;
        return new NormalMappingModifier(displacement_map, up_vector);
    }
}
示例#20
0
TextureInstance::TextureInstance(
    const char*             name,
    const ParamArray&       params,
    const size_t            texture_index)
  : Entity(g_class_uid, params)
  , impl(new Impl())
{
    set_name(name);

    impl->m_texture_index = texture_index;

    // Retrieve the texture addressing mode.
    const string addressing_mode = m_params.get_required<string>("addressing_mode", "wrap");
    if (addressing_mode == "clamp")
        impl->m_addressing_mode = TextureAddressingClamp;
    else if (addressing_mode == "wrap")
        impl->m_addressing_mode = TextureAddressingWrap;
    else
    {
        RENDERER_LOG_ERROR(
            "invalid value \"%s\" for parameter \"addressing_mode\", ",
            "using default value \"wrap\".",
            addressing_mode.c_str());
        impl->m_addressing_mode = TextureAddressingWrap;
    }

    // Retrieve the texture filtering mode.
    const string filtering_mode = m_params.get_required<string>("filtering_mode", "bilinear");
    if (filtering_mode == "nearest")
        impl->m_filtering_mode = TextureFilteringNearest;
    else if (filtering_mode == "bilinear")
        impl->m_filtering_mode = TextureFilteringBilinear;
    else
    {
        RENDERER_LOG_ERROR(
            "invalid value \"%s\" for parameter \"filtering_mode\", ",
            "using default value \"bilinear\".",
            filtering_mode.c_str());
        impl->m_filtering_mode = TextureFilteringBilinear;
    }

    // Retrieve multiplier.
    impl->m_multiplier = m_params.get_optional<float>("multiplier", 1.0f);
}
示例#21
0
void EnvironmentEDF::check_uniform(const char* input_name) const
{
    if (!m_inputs.source(input_name)->is_uniform())
    {
        RENDERER_LOG_ERROR(
            "the \"%s\" input of a \"%s\" must be bound to a scalar or a color.",
            input_name,
            get_model());
    }
}
示例#22
0
void ColorEntity::check_validity()
{
    // Check the number of color values.
    if (impl->m_color_space == ColorSpaceSpectral)
    {
        if (impl->m_values.empty())
        {
            RENDERER_LOG_ERROR("1 or more values required for \"spectral\" color space, got 0.");
        }
    }
    else
    {
        if (impl->m_values.size() != 1 && impl->m_values.size() != 3)
        {
            RENDERER_LOG_ERROR(
                "1 or 3 values required for \"%s\" color space, got " FMT_SIZE_T ".",
                color_space_name(impl->m_color_space),
                impl->m_values.size());
        }
    }
}
示例#23
0
void InputBinder::bind_assembly_entity_to_input(
    const Scene&                    scene,
    const SymbolTable&              scene_symbols,
    const Assembly&                 assembly,
    const SymbolTable&              assembly_symbols,
    const char*                     entity_type,
    const char*                     entity_name,
    const char*                     param_value,
    InputArray::iterator&           input)
{
    switch (assembly_symbols.lookup(param_value))
    {
      case SymbolTable::SymbolColor:
        bind_color_to_input(
            assembly.colors(),
            param_value,
            input);
        break;

      case SymbolTable::SymbolTextureInstance:
        bind_texture_instance_to_input(
            assembly.textures(),
            assembly.texture_instances(),
            assembly.get_uid(),
            entity_type,
            entity_name,
            param_value,
            input);
        break;

      case SymbolTable::SymbolNotFound:
        // No entity with this name was found in this scope.
        // Attempt to bind the input to a scene entity.
        bind_scene_entity_to_input(
            scene,
            scene_symbols,
            entity_type,
            entity_name,
            param_value,
            input);
        break;

      default:
        RENDERER_LOG_ERROR(
            "while defining %s \"%s\": cannot bind \"%s\" to parameter \"%s\".",
            entity_type,
            entity_name,
            param_value,
            input.name());
        ++m_error_count;
        break;
    }
}
示例#24
0
    // Return true if the scene passes basic integrity checks.
    bool check_scene() const
    {
        if (m_project.get_scene() == nullptr)
        {
            RENDERER_LOG_ERROR("project does not contain a scene.");
            return false;
        }

        if (m_project.get_frame() == nullptr)
        {
            RENDERER_LOG_ERROR("project does not contain a frame.");
            return false;
        }

        if (m_project.get_uncached_active_camera() == nullptr)
        {
            RENDERER_LOG_ERROR("no active camera in project.");
            return false;
        }

        return true;
    }
示例#25
0
Vector2d Camera::extract_film_dimensions() const
{
    const Vector2d DefaultFilmDimensions(0.025, 0.025);     // in meters

    const double DefaultAspectRatio =
        DefaultFilmDimensions[0] / DefaultFilmDimensions[1];

    Vector2d film_dimensions;

    if (has_params("film_width", "film_height"))
    {
        film_dimensions[0] = get_greater_than_zero("film_width", DefaultFilmDimensions[0]);
        film_dimensions[1] = get_greater_than_zero("film_height", DefaultFilmDimensions[1]);
    }
    else if (has_params("film_width", "aspect_ratio"))
    {
        const double aspect_ratio = get_greater_than_zero("aspect_ratio", DefaultAspectRatio);
        film_dimensions[0] = get_greater_than_zero("film_width", DefaultFilmDimensions[0]);
        film_dimensions[1] = film_dimensions[0] / aspect_ratio;
    }
    else if (has_params("film_height", "aspect_ratio"))
    {
        const double aspect_ratio = get_greater_than_zero("aspect_ratio", DefaultAspectRatio);
        film_dimensions[1] = get_greater_than_zero("film_height", DefaultFilmDimensions[1]);
        film_dimensions[0] = film_dimensions[1] * aspect_ratio;
    }
    else
    {
        film_dimensions =
            m_params.get_required<Vector2d>("film_dimensions", DefaultFilmDimensions);

        if (film_dimensions[0] <= 0.0 || film_dimensions[1] <= 0.0)
        {
            RENDERER_LOG_ERROR(
                "while defining camera \"%s\": invalid value \"%f %f\" for parameter \"%s\", "
                "using default value \"%f %f\".",
                get_name(),
                film_dimensions[0],
                film_dimensions[1],
                "film_dimensions",
                DefaultFilmDimensions[0],
                DefaultFilmDimensions[1]);

            film_dimensions = DefaultFilmDimensions;
        }
    }

    return film_dimensions;
}
示例#26
0
void InputBinder::bind_assembly_entity_inputs(
    const Scene&                    scene,
    const SymbolTable&              scene_symbols,
    const Assembly&                 assembly,
    const SymbolTable&              assembly_symbols,
    const char*                     entity_type,
    const char*                     entity_name,
    const ParamArray&               entity_params,
    InputArray&                     entity_inputs)
{
    for (each<InputArray> i = entity_inputs; i; ++i)
    {
        InputArray::iterator& input = *i;

        // Retrieve the value assigned to this input in the parameter array.
        string param_value;
        try
        {
            param_value = entity_params.get<string>(input.name());
        }
        catch (const ExceptionDictionaryItemNotFound&)
        {
            // Couldn't find an assignment to this input.
            if (!input.is_optional())
            {
                RENDERER_LOG_ERROR(
                    "while defining %s \"%s\": required parameter \"%s\" missing.",
                    entity_type,
                    entity_name,
                    input.name());
                ++m_error_count;
            }
            continue;
        }

        if (!try_bind_scalar_to_input(param_value, input))
        {
            bind_assembly_entity_to_input(
                scene,
                scene_symbols,
                assembly,
                assembly_symbols,
                entity_type,
                entity_name,
                param_value.c_str(),
                input);
        }
    }
}
示例#27
0
bool ConnectableEntity::check_uniform(const char* input_name) const
{
    const Source* source = m_inputs.source(input_name);

    assert(source);

    if (source->is_uniform())
        return true;

    RENDERER_LOG_ERROR(
        "the \"%s\" input of \"%s\" must be bound to a scalar or a color.",
        input_name,
        get_name());

    return false;
}
示例#28
0
void Camera::extract_focal_distance(
    bool&               autofocus_enabled,
    Vector2d&           autofocus_target,
    double&             focal_distance) const
{
    const Vector2d DefaultAFTarget(0.5);        // in NDC
    const double DefaultFocalDistance = 1.0;    // in meters

    if (has_param("focal_distance"))
    {
        if (has_param("autofocus_target"))
        {
            RENDERER_LOG_WARNING(
                "while defining camera \"%s\": autofocus is enabled; \"focal_distance\" parameter "
                "will be ignored.",
                get_path().c_str());

            autofocus_enabled = true;
            autofocus_target = m_params.get_required<Vector2d>("autofocus_target", DefaultAFTarget);
            focal_distance = 0.0;
        }
        else
        {
            autofocus_enabled = false;
            autofocus_target = DefaultAFTarget;
            focal_distance = m_params.get_required<double>("focal_distance", DefaultFocalDistance);
        }
    }
    else if (has_param("autofocus_target"))
    {
        autofocus_enabled = true;
        autofocus_target = m_params.get_required<Vector2d>("autofocus_target", DefaultAFTarget);
        focal_distance = 0.0;
    }
    else
    {
        RENDERER_LOG_ERROR(
            "while defining camera \"%s\": no \"focal_distance\" or \"autofocus_target\" parameter found; "
            "using default focal distance value \"%f\".",
            get_path().c_str(),
            DefaultFocalDistance);

        autofocus_enabled = false;
        autofocus_target = DefaultAFTarget;
        focal_distance = DefaultFocalDistance;
    }
}
示例#29
0
RenderLayerRule::RenderLayerRule(
    const char*         name,
    const ParamArray&   params)
  : Entity(g_class_uid, params)
  , impl(new Impl())
{
    set_name(name);

    const EntityDefMessageContext context("render layer rule", this);

    impl->m_render_layer = params.get_required<string>("render_layer", "", context);
    impl->m_order = params.get_required<int>("order", 0, context);

    const string entity_type = params.get_optional<string>("entity_type", "");

    if (entity_type == "")
        impl->m_entity_type_uid = UniqueID(~0);
    else if (entity_type == "assembly")
        impl->m_entity_type_uid = Assembly::get_class_uid();
    else if (entity_type == "assembly_instance")
        impl->m_entity_type_uid = AssemblyInstance::get_class_uid();
    else if (entity_type == "edf")
        impl->m_entity_type_uid = EDF::get_class_uid();
    else if (entity_type == "environment_edf")
        impl->m_entity_type_uid = EnvironmentEDF::get_class_uid();
    else if (entity_type == "environment_shader")
        impl->m_entity_type_uid = EnvironmentShader::get_class_uid();
    else if (entity_type == "light")
        impl->m_entity_type_uid = Light::get_class_uid();
    else if (entity_type == "material")
        impl->m_entity_type_uid = Material::get_class_uid();
    else if (entity_type == "object")
        impl->m_entity_type_uid = Object::get_class_uid();
    else if (entity_type == "object_instance")
        impl->m_entity_type_uid = ObjectInstance::get_class_uid();
    else if (entity_type == "surface_shader")
        impl->m_entity_type_uid = SurfaceShader::get_class_uid();
    else
    {
        RENDERER_LOG_ERROR(
            "%s: invalid value \"%s\" for parameter \"%s\", using default value \"\".",
            context.get(),
            entity_type.c_str(),
            "entity_type");
        impl->m_entity_type_uid = UniqueID(~0);
    }
}
void ExpressionEditorWindow::apply_expression()
{
    const string expression = m_editor->getExpr();
    const SeAppleseedExpr expr(expression);

    if (expr.isValid())
    {
        m_error->hide();
        RENDERER_LOG_INFO("expression successfully applied.");
        emit signal_expression_applied(m_widget_name, QString::fromStdString(expression));
    }
    else
    {
        m_error->show();
        RENDERER_LOG_ERROR("expression error: %s", expr.parseError().c_str());
    }
}