示例#1
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;
    }
}
示例#2
0
AssemblyItem::AssemblyItem(
    Assembly&       assembly,
    BaseGroup&      parent,
    BaseGroupItem*  parent_item,
    ProjectBuilder& project_builder,
    ParamArray&     settings)
  : BaseGroupItem(g_class_uid, assembly, project_builder, settings)
  , m_assembly(assembly)
  , m_parent(parent)
  , m_parent_item(parent_item)
  , m_project_builder(project_builder)
{
    set_title(QString::fromAscii(assembly.get_name()));

    set_allow_edition(false);

    insertChild(
        3,
        m_bsdf_collection_item = add_multi_model_collection_item<BSDF>(assembly.bsdfs()));

    insertChild(
        4,
        m_edf_collection_item = add_multi_model_collection_item<EDF>(assembly.edfs()));

    insertChild(
        5,
        m_surface_shader_collection_item = add_multi_model_collection_item<SurfaceShader>(assembly.surface_shaders()));

    insertChild(
        6,
        m_material_collection_item = add_multi_model_collection_item<Material>(assembly.materials()));

    insertChild(
        7,
        m_light_collection_item = add_multi_model_collection_item<Light>(assembly.lights()));

    insertChild(
        8,
        m_object_collection_item =
            new ObjectCollectionItem(
                assembly.objects(),
                assembly,
                this,
                project_builder,
                settings));

    insertChild(
        9,
        m_object_instance_collection_item =
            new ObjectInstanceCollectionItem(
                new_guid(),
                EntityTraits<ObjectInstance>::get_human_readable_collection_type_name(),
                assembly,
                project_builder));
    m_object_instance_collection_item->add_items(assembly.object_instances());
}
StringDictionary EntityBrowser<Assembly>::get_entities(const Assembly& assembly, const string& type) const
{
    StringDictionary entities;

    if (type == "bsdf")
    {
        entities = build_entity_dictionary(assembly.bsdfs());
    }
    else if (type == "edf")
    {
        entities = build_entity_dictionary(assembly.edfs());
    }
    else if (type == "material")
    {
        entities = build_entity_dictionary(assembly.materials());
    }
    else if (type == "surface_shader")
    {
        entities = build_entity_dictionary(assembly.surface_shaders());
    }
    else if (type == "environment_edf")
    {
        entities = build_entity_dictionary(get_parent_scene(&assembly)->environment_edfs());
    }
    else if (type == "environment_shader")
    {
        entities = build_entity_dictionary(get_parent_scene(&assembly)->environment_shaders());
    }
    else
    {
        entities = EntityBrowser<BaseGroup>::get_entities(type);
    }

    const Assembly* parent_assembly = dynamic_cast<const Assembly*>(assembly.get_parent());

    if (parent_assembly)
    {
        merge_dictionary(entities, get_entities(*parent_assembly, type));
    }
    else
    {
        const Scene* parent_scene = dynamic_cast<const Scene*>(assembly.get_parent());
        assert(parent_scene);

        merge_dictionary(entities, EntityBrowser<Scene>(*parent_scene).get_entities(type));
    }

    return entities;
}
示例#4
0
    void collect_relations_from_assembly(Assembly& assembly)
    {
        collect_relations_from(assembly.colors());
        collect_relations_from(assembly.textures());
        collect_relations_from(assembly.texture_instances());
        collect_relations_from(assembly.shader_groups());
        collect_relations_from(assembly.assembly_instances());

        collect_relations_from(assembly.bsdfs());
        collect_relations_from(assembly.bssrdfs());
        collect_relations_from(assembly.edfs());
        collect_relations_from(assembly.surface_shaders());
        collect_relations_from(assembly.materials());
        collect_relations_from(assembly.lights());
        collect_relations_from(assembly.objects());
        collect_relations_from(assembly.object_instances());
        collect_relations_from(assembly.volumes());

        for (auto& child_assembly : assembly.assemblies())
            collect_relations_from_assembly(child_assembly);

        // Lights are implicitly referenced by their parent assembly.
        for (auto& light : assembly.lights())
        {
            const InputBinder::ReferencedEntity referenced_entity(assembly.lights(), &light);
            insert_relation(referenced_entity, assembly);
        }

        // Object instances are implicitly referenced by their parent assembly.
        for (auto& object_instance : assembly.object_instances())
        {
            const InputBinder::ReferencedEntity referenced_entity(assembly.object_instances(), &object_instance);
            insert_relation(referenced_entity, assembly);
        }

        // Assembly instances are implicitly referenced by their parent assembly.
        for (auto& assembly_instance : assembly.assembly_instances())
        {
            const InputBinder::ReferencedEntity referenced_entity(assembly.assembly_instances(), &assembly_instance);
            insert_relation(referenced_entity, assembly);
        }
    }
示例#5
0
    void remove_unused_entities_from_assembly(Assembly& assembly)
    {
        remove_unused_entities_from(assembly.colors());
        remove_unused_entities_from(assembly.textures());
        remove_unused_entities_from(assembly.texture_instances());
        remove_unused_entities_from(assembly.shader_groups());
        remove_unused_entities_from(assembly.assembly_instances());

        remove_unused_entities_from(assembly.bsdfs());
        remove_unused_entities_from(assembly.bssrdfs());
        remove_unused_entities_from(assembly.edfs());
        remove_unused_entities_from(assembly.surface_shaders());
        remove_unused_entities_from(assembly.materials());
        remove_unused_entities_from(assembly.lights());
        remove_unused_entities_from(assembly.objects());
        remove_unused_entities_from(assembly.object_instances());
        remove_unused_entities_from(assembly.volumes());

        for (auto& child_assembly : assembly.assemblies())
            remove_unused_entities_from_assembly(child_assembly);
    }
示例#6
0
bool InputBinder::try_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)
{
    if (input.format() == InputFormatEntity)
    {
        #define BIND(symbol, collection)                        \
            case symbol:                                        \
              input.bind(collection.get_by_name(param_value));  \
              return true

        switch (assembly_symbols.lookup(param_value))
        {
          BIND(SymbolTable::SymbolColor, assembly.colors());
          BIND(SymbolTable::SymbolTexture, assembly.textures());
          BIND(SymbolTable::SymbolTextureInstance, assembly.texture_instances());
          BIND(SymbolTable::SymbolBSDF, assembly.bsdfs());
          BIND(SymbolTable::SymbolBSSRDF, assembly.bssrdfs());
          BIND(SymbolTable::SymbolEDF, assembly.edfs());
#ifdef APPLESEED_WITH_OSL
          BIND(SymbolTable::SymbolShaderGroup, assembly.shader_groups());
#endif
          BIND(SymbolTable::SymbolSurfaceShader, assembly.surface_shaders());
          BIND(SymbolTable::SymbolMaterial, assembly.materials());
          BIND(SymbolTable::SymbolLight, assembly.lights());
          BIND(SymbolTable::SymbolObject, assembly.objects());
          BIND(SymbolTable::SymbolObjectInstance, assembly.object_instances());
        }

        #undef BIND
    }
    else
    {
        switch (assembly_symbols.lookup(param_value))
        {
          case SymbolTable::SymbolColor:
            bind_color_to_input(
                assembly.colors(),
                param_value,
                input);
            return true;

          case SymbolTable::SymbolTextureInstance:
            bind_texture_instance_to_input(
                assembly.texture_instances(),
                assembly.get_uid(),
                entity_type,
                entity_name,
                param_value,
                input);
            return true;
        }
    }

    return false;
}
示例#7
0
void InputBinder::bind_assembly_entities_inputs(
    const Scene&                    scene,
    const SymbolTable&              scene_symbols,
    const Assembly&                 assembly)
{
    // Build the symbol table of the assembly.
    SymbolTable assembly_symbols;
    build_assembly_symbol_table(assembly, assembly_symbols);

    // Push the assembly and its symbol table to the stack.
    AssemblyInfo info;
    info.m_assembly = &assembly;
    info.m_assembly_symbols = &assembly_symbols;
    m_assembly_info.push_back(info);

    // Bind textures to texture instances.
    // Other entities might need to access the textures bound to texture instances,
    // so binding of textures to texture instances must come first.
    for (each<TextureInstanceContainer> i = assembly.texture_instances(); i; ++i)
    {
        i->unbind_texture();

        for (AssemblyInfoIt j = m_assembly_info.rbegin(); j != m_assembly_info.rend(); ++j)
            i->bind_texture(j->m_assembly->textures());

        i->bind_texture(scene.textures());

        i->check_texture();
    }

    // Bind BSDFs inputs.
    for (each<BSDFContainer> i = assembly.bsdfs(); i; ++i)
    {
        bind_assembly_entity_inputs(
            scene,
            scene_symbols,
            SymbolTable::symbol_name(SymbolTable::SymbolBSDF),
            *i);
    }

    // Bind BSSRDFs inputs.
    for (each<BSSRDFContainer> i = assembly.bssrdfs(); i; ++i)
    {
        bind_assembly_entity_inputs(
            scene,
            scene_symbols,
            SymbolTable::symbol_name(SymbolTable::SymbolBSSRDF),
            *i);
    }

    // Bind EDFs inputs.
    for (each<EDFContainer> i = assembly.edfs(); i; ++i)
    {
        bind_assembly_entity_inputs(
            scene,
            scene_symbols,
            SymbolTable::symbol_name(SymbolTable::SymbolEDF),
            *i);
    }

#ifdef APPLESEED_WITH_OSL
    // Bind ShaderGroups inputs.
    for (each<ShaderGroupContainer> i = assembly.shader_groups(); i; ++i)
    {
        bind_assembly_entity_inputs(
            scene,
            scene_symbols,
            SymbolTable::symbol_name(SymbolTable::SymbolShaderGroup),
            *i);
    }
#endif

    // Bind surface shaders inputs.
    for (each<SurfaceShaderContainer> i = assembly.surface_shaders(); i; ++i)
    {
        bind_assembly_entity_inputs(
            scene,
            scene_symbols,
            SymbolTable::symbol_name(SymbolTable::SymbolSurfaceShader),
            *i);
    }

    // Bind materials inputs.
    for (each<MaterialContainer> i = assembly.materials(); i; ++i)
    {
        bind_assembly_entity_inputs(
            scene,
            scene_symbols,
            SymbolTable::symbol_name(SymbolTable::SymbolMaterial),
            *i);
    }

    // Bind lights inputs.
    for (each<LightContainer> i = assembly.lights(); i; ++i)
    {
        bind_assembly_entity_inputs(
            scene,
            scene_symbols,
            SymbolTable::symbol_name(SymbolTable::SymbolLight),
            *i);
    }

    // Bind objects inputs.
    for (each<ObjectContainer> i = assembly.objects(); i; ++i)
    {
        bind_assembly_entity_inputs(
            scene,
            scene_symbols,
            SymbolTable::symbol_name(SymbolTable::SymbolObject),
            *i);
    }

    // Bind objects to object instances. This must be done before binding materials.
    for (each<ObjectInstanceContainer> i = assembly.object_instances(); i; ++i)
    {
        i->unbind_object();

        for (AssemblyInfoIt j = m_assembly_info.rbegin(); j != m_assembly_info.rend(); ++j)
            i->bind_object(j->m_assembly->objects());

        i->check_object();
    }

    // Bind materials to object instances.
    for (each<ObjectInstanceContainer> i = assembly.object_instances(); i; ++i)
    {
        i->unbind_materials();

        for (AssemblyInfoIt j = m_assembly_info.rbegin(); j != m_assembly_info.rend(); ++j)
            i->bind_materials(j->m_assembly->materials());

        i->check_materials();
    }

    // Bind assemblies to assembly instances.
    for (each<AssemblyInstanceContainer> i = assembly.assembly_instances(); i; ++i)
    {
        i->unbind_assembly();

        for (AssemblyInfoIt j = m_assembly_info.rbegin(); j != m_assembly_info.rend(); ++j)
            i->bind_assembly(j->m_assembly->assemblies());

        i->bind_assembly(scene.assemblies());

        i->check_assembly();
    }

    // Recurse into child assemblies.
    for (const_each<AssemblyContainer> i = assembly.assemblies(); i; ++i)
        bind_assembly_entities_inputs(scene, scene_symbols, *i);

    // Pop the information about this assembly from the stack.
    m_assembly_info.pop_back();
}
示例#8
0
void InputBinder::bind_assembly_entities_inputs(
    const Scene&                    scene,
    const SymbolTable&              scene_symbols,
    const Assembly&                 assembly,
    const SymbolTable&              assembly_symbols)
{
    // Bind BSDFs inputs.
    for (each<BSDFContainer> i = assembly.bsdfs(); i; ++i)
    {
        bind_assembly_entity_inputs(
            scene,
            scene_symbols,
            assembly,
            assembly_symbols,
            SymbolTable::symbol_name(SymbolTable::SymbolBSDF),
            i->get_name(),
            i->get_parameters(),
            i->get_inputs());
    }

    // Bind EDFs inputs.
    for (each<EDFContainer> i = assembly.edfs(); i; ++i)
    {
        bind_assembly_entity_inputs(
            scene,
            scene_symbols,
            assembly,
            assembly_symbols,
            SymbolTable::symbol_name(SymbolTable::SymbolEDF),
            i->get_name(),
            i->get_parameters(),
            i->get_inputs());
    }

    // Bind surface shaders inputs.
    for (each<SurfaceShaderContainer> i = assembly.surface_shaders(); i; ++i)
    {
        bind_assembly_entity_inputs(
            scene,
            scene_symbols,
            assembly,
            assembly_symbols,
            SymbolTable::symbol_name(SymbolTable::SymbolSurfaceShader),
            i->get_name(),
            i->get_parameters(),
            i->get_inputs());
    }

    // Bind materials inputs.
    for (each<MaterialContainer> i = assembly.materials(); i; ++i)
    {
        bind_assembly_entity_inputs(
            scene,
            scene_symbols,
            assembly,
            assembly_symbols,
            SymbolTable::symbol_name(SymbolTable::SymbolMaterial),
            i->get_name(),
            i->get_parameters(),
            i->get_inputs());

        i->bind_entities(
            assembly.surface_shaders(),
            assembly.bsdfs(),
            assembly.edfs());
    }

    // Bind lights inputs.
    for (each<LightContainer> i = assembly.lights(); i; ++i)
    {
        bind_assembly_entity_inputs(
            scene,
            scene_symbols,
            assembly,
            assembly_symbols,
            SymbolTable::symbol_name(SymbolTable::SymbolLight),
            i->get_name(),
            i->get_parameters(),
            i->get_inputs());
    }

    // Bind object instances inputs.
    for (each<ObjectInstanceContainer> i = assembly.object_instances(); i; ++i)
        i->bind_entities(assembly.materials());
}
示例#9
0
AssemblyItem::AssemblyItem(
    EntityEditorContext&    editor_context,
    Assembly&               assembly,
    BaseGroup&              parent,
    BaseGroupItem*          parent_item)
  : BaseGroupItem(editor_context, g_class_uid, assembly)
  , m_assembly(assembly)
  , m_assembly_uid(assembly.get_uid())
  , m_parent(parent)
  , m_parent_item(parent_item)
{
    set_title(QString::fromAscii(assembly.get_name()));

    set_allow_edition(false);

    insertChild(
        3,
        m_bsdf_collection_item = add_multi_model_collection_item<BSDF>(assembly.bsdfs()));

    insertChild(
        4,
        m_bssrdf_collection_item = add_multi_model_collection_item<BSSRDF>(assembly.bssrdfs()));

    insertChild(
        5,
        m_edf_collection_item = add_multi_model_collection_item<EDF>(assembly.edfs()));

    insertChild(
        6,
        m_surface_shader_collection_item = add_multi_model_collection_item<SurfaceShader>(assembly.surface_shaders()));

    insertChild(
        7,
        m_material_collection_item = new MaterialCollectionItem(
            m_editor_context,
            assembly.materials(),
            assembly,
            this));

    insertChild(
        8,
        m_light_collection_item = add_multi_model_collection_item<Light>(assembly.lights()));

    insertChild(
        9,
        m_object_collection_item =
            new ObjectCollectionItem(
                m_editor_context,
                assembly.objects(),
                assembly,
                this));

    insertChild(
        10,
        m_object_instance_collection_item =
            new ObjectInstanceCollectionItem(
                m_editor_context,
                new_guid(),
                EntityTraits<ObjectInstance>::get_human_readable_collection_type_name(),
                assembly));
    m_object_instance_collection_item->add_items(assembly.object_instances());

    insertChild(
        11,
        m_volume_collection_item = add_multi_model_collection_item<Volume>(assembly.volumes()));

    m_editor_context.m_item_registry.insert(m_assembly, this);
}
示例#10
0
    void add_cube(
        Assembly&           assembly,
        const size_t        ix,
        const size_t        iy,
        const double        fx,
        const double        fz,
        const Color3b&      color,
        const Transformd&   transform) override
    {
        const string color_suffix = color_to_string(color);
        const string color_name = "color_" + color_suffix;
        const string material_name = "material_" + color_suffix;

        if (assembly.colors().get_by_name(color_name.c_str()) == 0)
        {
            const Color3f reflectance = Color3f(color) * (1.0f / 255);
            assembly.colors().insert(
                ColorEntityFactory::create(
                    color_name.c_str(),
                    ParamArray()
                        .insert("color_space", "srgb"),
                    ColorValueArray(3, &reflectance[0])));

            const string brdf_name = "brdf_" + color_suffix;
            assembly.bsdfs().insert(
                DisneyBRDFFactory().create(
                    brdf_name.c_str(),
                    ParamArray()
                        .insert("anisotropic", 0.0)
                        .insert("base_color", color_name)
                        .insert("clearcoat", 1.0)
                        .insert("clearcoat_gloss", 0.9)
                        .insert("metallic", 0.0)
                        .insert("roughness", 0.3)
                        .insert("sheen", 0.0)
                        .insert("sheen_tint", 0.0)
                        .insert("specular", 0.9)
                        .insert("specular_tint", 1.0)
                        .insert("subsurface", 1.0)));

            assembly.materials().insert(
                GenericMaterialFactory().create(
                    material_name.c_str(),
                    ParamArray()
                        .insert("surface_shader", "physical_surface_shader")
                        .insert("bsdf", brdf_name)));
        }

        // Create an assembly for this cube.
        const string coordinates_suffix = coordinates_to_string(ix, iy);
        const string cube_assembly_name = "assembly_" + coordinates_suffix;
        auto_release_ptr<Assembly> cube_assembly(
            AssemblyFactory().create(cube_assembly_name.c_str()));

        // Instantiate the cube mesh object (from the parent assembly) into this assembly.
        cube_assembly->object_instances().insert(
            ObjectInstanceFactory::create(
                "cube.0_inst",
                ParamArray(),
                "cube.0",
                Transformd::identity(),
                StringDictionary()
                    .insert("default", material_name)));

        // Create an instance of the cube assembly.
        const string cube_assembly_inst_name = cube_assembly_name + "_inst";
        auto_release_ptr<AssemblyInstance> cube_assembly_inst(
            AssemblyInstanceFactory::create(
                cube_assembly_inst_name.c_str(),
                ParamArray(),
                cube_assembly_name.c_str()));
        cube_assembly_inst->transform_sequence().set_transform(0.0, transform);

        // Insert both the cube assembly and its instance into the parent assembly.
        assembly.assemblies().insert(cube_assembly);
        assembly.assembly_instances().insert(cube_assembly_inst);
    }
示例#11
0
    void initialize_assembly(
        Project&            project,
        Assembly&           assembly,
        const size_t        image_width,
        const size_t        image_height) override
    {
        assembly.textures().insert(
            DiskTexture2dFactory().create(
                "cubes_texture",
                ParamArray()
                    .insert("filename", "heightfield.png")
                    .insert("color_space", "srgb"),
                project.search_paths()));

        assembly.texture_instances().insert(
            TextureInstanceFactory::create(
                "cubes_texture_instance",
                ParamArray()
                    .insert("filtering_mode", "nearest")
                    .insert("addressing_mode", "wrap"),
                "cubes_texture"));

        assembly.bsdfs().insert(
            DisneyBRDFFactory().create(
                "cubes_brdf",
                ParamArray()
                    .insert("anisotropic", 0.0)
                    .insert("base_color", "cubes_texture_instance")
                    .insert("clearcoat", 1.0)
                    .insert("clearcoat_gloss", 0.9)
                    .insert("metallic", 0.0)
                    .insert("roughness", 0.3)
                    .insert("sheen", 0.0)
                    .insert("sheen_tint", 0.0)
                    .insert("specular", 0.9)
                    .insert("specular_tint", 1.0)
                    .insert("subsurface", 1.0)));

        assembly.surface_shaders().insert(
            PhysicalSurfaceShaderFactory().create(
                "physical_surface_shader",
                ParamArray()));

        assembly.materials().insert(
            GenericMaterialFactory().create(
                "cubes_material",
                ParamArray()
                    .insert("surface_shader", "physical_surface_shader")
                    .insert("bsdf", "cubes_brdf")));

        // Load the cube mesh object from disk.
        MeshObjectArray objects;
        MeshObjectReader::read(
            project.search_paths(),
            "cube",
            ParamArray()
                .insert("filename", "cube.obj"),
            objects);
        assert(objects.size() == 1);
        m_cube.reset(objects[0]);

        // Create the baked mesh object.
        m_mesh = MeshObjectFactory().create("cubes", ParamArray());

        // Reserve memory into the baked mesh object.
        const size_t cube_count = image_width * image_height;
        m_mesh->reserve_vertices(m_cube->get_vertex_count() * cube_count);
        m_mesh->reserve_vertex_normals(m_cube->get_vertex_normal_count() * cube_count);
        m_mesh->reserve_tex_coords(cube_count);
        m_mesh->reserve_triangles(m_cube->get_triangle_count() * cube_count);
    }