// // This source file is part of appleseed. // Visit https://appleseedhq.net/ for additional information and resources. // // This software is released under the MIT license. // // Copyright (c) 2010-2013 Francois Beaune, Jupiter Jazz Limited // Copyright (c) 2014-2018 Francois Beaune, The appleseedhq Organization // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // #pragma once // appleseed.renderer headers. #include "renderer/modeling/entity/entity.h" #include "renderer/modeling/entity/entitymap.h" #include "renderer/modeling/entity/entityvector.h" #include "renderer/utility/paramarray.h" // appleseed.foundation headers. #include "foundation/core/exceptions/stringexception.h" #include "foundation/utility/foreach.h" #include "foundation/utility/string.h" // Standard headers. #include #include // Forward declarations. namespace renderer { class Assembly; } namespace renderer { class AssemblyInstance; } namespace renderer { class BSDF; } namespace renderer { class BSSRDF; } namespace renderer { class Camera; } namespace renderer { class ColorEntity; } namespace renderer { class EDF; } namespace renderer { class EnvironmentEDF; } namespace renderer { class EnvironmentShader; } namespace renderer { class Light; } namespace renderer { class Material; } namespace renderer { class Object; } namespace renderer { class ObjectInstance; } namespace renderer { class Shader; } namespace renderer { class ShaderConnection; } namespace renderer { class ShaderGroup; } namespace renderer { class ShaderParam; } namespace renderer { class SurfaceShader; } namespace renderer { class Texture; } namespace renderer { class TextureInstance; } namespace renderer { class Volume; } namespace renderer { // // Entity containers. // typedef TypedEntityMap AssemblyContainer; typedef TypedEntityMap AssemblyInstanceContainer; typedef TypedEntityVector BSDFContainer; typedef TypedEntityVector BSSRDFContainer; typedef TypedEntityVector CameraContainer; typedef TypedEntityVector ColorContainer; typedef TypedEntityVector EDFContainer; typedef TypedEntityVector EnvironmentEDFContainer; typedef TypedEntityVector EnvironmentShaderContainer; typedef TypedEntityVector LightContainer; typedef TypedEntityVector MaterialContainer; typedef TypedEntityVector ObjectContainer; typedef TypedEntityVector ObjectInstanceContainer; typedef TypedEntityVector ShaderContainer; typedef TypedEntityVector ShaderConnectionContainer; typedef TypedEntityVector ShaderGroupContainer; typedef TypedEntityVector ShaderParamContainer; typedef TypedEntityVector SurfaceShaderContainer; typedef TypedEntityVector TextureContainer; typedef TypedEntityVector TextureInstanceContainer; typedef TypedEntityVector VolumeContainer; // // Exception thrown when an entity is not found. // class ExceptionUnknownEntity : public foundation::StringException { public: explicit ExceptionUnknownEntity( const char* entity_name, const Entity* context = nullptr); const std::string& get_context_path() const; private: const std::string m_context_path; }; // // Retrieve a mandatory entity from a container. // Returns nullptr if the parameter does not exist. // Throws a renderer::ExceptionUnknownEntity exception if the requested entity does not exist. // template T* get_required_entity( const Container& container, const ParamArray& params, const std::string& param_name); // // Retrieve an optional entity from a container. // Returns nullptr if the parameter does not exist. // Throws a renderer::ExceptionUnknownEntity exception if the requested entity does not exist. // template T* get_optional_entity( const Container& container, const ParamArray& params, const std::string& param_name); // // Generate a new name for an entity in a collection. // template std::vector collect_entity_names( const EntityContainer& entities); template std::string make_unique_name( const std::string& prefix, const EntityContainer& entities); std::string make_unique_name( const std::string& prefix, const std::vector& entity_names); // // Implementation. // template T* get_required_entity( const Container& container, const ParamArray& params, const std::string& param_name) { const std::string entity_name = params.get_required(param_name.c_str(), std::string()); if (entity_name.empty()) return 0; T* entity = container.get_by_name(entity_name.c_str()); if (entity == 0) throw ExceptionUnknownEntity(entity_name.c_str()); return entity; } template T* get_optional_entity( const Container& container, const ParamArray& params, const std::string& param_name) { const std::string entity_name = params.get_optional(param_name.c_str(), std::string()); if (entity_name.empty()) return 0; T* entity = container.get_by_name(entity_name.c_str()); if (entity == 0) throw ExceptionUnknownEntity(entity_name.c_str()); return entity; } template std::vector collect_entity_names( const EntityContainer& entities) { std::vector names; names.reserve(entities.size()); for (foundation::const_each i = entities; i; ++i) names.push_back(i->get_name()); return names; } template std::string make_unique_name( const std::string& prefix, const EntityContainer& entities) { return make_unique_name( prefix, collect_entity_names(entities)); } inline std::string make_unique_name( const std::string& prefix, const std::vector& entity_names) { int max_number = 0; for (size_t i = 0, e = entity_names.size(); i < e; ++i) { const std::string& entity_name = entity_names[i]; if (foundation::starts_with(entity_name, prefix)) { try { const std::string entity_name_suffix = entity_name.substr(prefix.size()); const int number = foundation::from_string(entity_name_suffix); if (max_number < number) max_number = number; } catch (const foundation::ExceptionStringConversionError&) { } } } return prefix + foundation::to_string(max_number + 1); } } // namespace renderer