| 1854 | } |
| 1855 | |
| 1856 | IfcUtil::IfcBaseClass* IfcFile::addEntity(IfcUtil::IfcBaseClass* entity, int id) { |
| 1857 | if (id != -1) { |
| 1858 | bool id_already_exists = false; |
| 1859 | try { |
| 1860 | if (check_existance_before_adding) { |
| 1861 | instance_by_id(id); |
| 1862 | id_already_exists = true; |
| 1863 | } |
| 1864 | } catch (...) {} |
| 1865 | if (id_already_exists) { |
| 1866 | throw IfcParse::IfcException("An instance with id " + boost::lexical_cast<std::string>(id) + " is already part of this file"); |
| 1867 | } |
| 1868 | } |
| 1869 | |
| 1870 | if (entity->declaration().schema() != schema()) { |
| 1871 | throw IfcParse::IfcException("Unabled to add instance from " + entity->declaration().schema()->name() + " schema to file with " + schema()->name() + " schema"); |
| 1872 | } |
| 1873 | |
| 1874 | // If this instance has been inserted before, return |
| 1875 | // a reference to the copy that was created from it. |
| 1876 | entity_entity_map_t::iterator mit = entity_file_map_.find(entity->identity()); |
| 1877 | if (mit != entity_file_map_.end()) { |
| 1878 | return mit->second; |
| 1879 | } |
| 1880 | |
| 1881 | IfcUtil::IfcBaseClass* new_entity = entity; |
| 1882 | |
| 1883 | // Obtain all forward references by a depth-first |
| 1884 | // traversal and add them to the file. |
| 1885 | try { |
| 1886 | aggregate_of_instance::ptr entity_attributes = traverse(entity, 1); |
| 1887 | for (aggregate_of_instance::it it = entity_attributes->begin(); it != entity_attributes->end(); ++it) { |
| 1888 | if (*it != entity) { |
| 1889 | entity_entity_map_t::iterator mit2 = entity_file_map_.find((*it)->identity()); |
| 1890 | if (mit2 == entity_file_map_.end()) { |
| 1891 | entity_file_map_.insert(entity_entity_map_t::value_type((*it)->identity(), addEntity(*it))); |
| 1892 | } |
| 1893 | } |
| 1894 | } |
| 1895 | } catch (...) { |
| 1896 | Logger::Message(Logger::LOG_ERROR, "Failed to visit forward references of", entity); |
| 1897 | } |
| 1898 | |
| 1899 | // See whether the instance is already part of a file |
| 1900 | if (entity->file_ != nullptr) { |
| 1901 | if (entity->file_ == this) { |
| 1902 | if (entity->declaration().as_entity() == nullptr) { |
| 1903 | // While not a mapping that can be queried, we do need to free the instance later on |
| 1904 | // @todo. why (over?)write this when adding from the same file? |
| 1905 | std::visit([new_entity](auto& m) { |
| 1906 | if constexpr (std::is_same_v<std::decay_t<decltype(m)>, impl::in_memory_file_storage>) { |
| 1907 | // @todo not freed yet |
| 1908 | m.tbyid_.insert({ new_entity->identity(), new_entity }); |
| 1909 | } |
| 1910 | }, storage_); |
| 1911 | } |
| 1912 | |
| 1913 | // If it is part of this file |
no test coverage detected