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); } }
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); }
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(); }
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); }