#ifndef MAPPING_H #define MAPPING_H #include "../abstract_mapping.h" #include "../../ifcparse/macros.h" #include "../../ifcparse/file.h" #include "../../ifcparse/logger.h" #include #include #include #include INCLUDE_SCHEMA(../../ifcparse/schemas, IfcSchema) #include INCLUDE_SCHEMA_DEFINITIONS(../../ifcparse/schemas, IfcSchema) namespace ifcopenshell { namespace geom { class POSTFIX_SCHEMA(mapping) : public abstract_mapping { private: ifcopenshell::file* file_; double length_unit_, angle_unit_; std::string length_unit_name_; std::map cache_; std::mutex cache_guard_; // provides mutually exclusive access to cache_ const ifcopenshell::declaration* placement_rel_to_type_; const express::base placement_rel_to_instance_; Eigen::Matrix4d offset_and_rotation_ = Eigen::Matrix4d::Identity(); void initialize_units_(); void addRepresentationsFromContextIds(std::vector&); void addRepresentationsFromPriorities(std::vector&); void addRepresentationsFromDefaultContexts(std::vector&); void ensureRepresentationContextCache_(); // Set of instances to mark failures that are intended, such as representations not // resulting in any items due to dimensionality filters. std::set failed_on_purpose_; std::set not_reusable_maps_; std::unordered_set representation_context_cache_; std::vector representation_context_priority_cache_; std::set representation_context_cache_ids_; std::vector representation_context_cache_priorities_; settings::OutputDimensionalityTypes representation_context_cache_dimensionality_ = settings::SURFACES_AND_SOLIDS; bool representation_context_cache_has_context_ids_ = false; bool representation_context_cache_has_context_priorities_ = false; bool representation_context_cache_valid_ = false; std::mutex representation_context_cache_guard_; template void process_mapping(bool& matched, taxonomy::ptr& item, const express::base& inst) { if (!item && inst.as()) { matched = true; try { item = map_impl(inst.as()); if (item != nullptr) { if (!item->instance) { item->instance = inst; } try { if (inst.as() && !inst.as() && /* @todo */ (item->kind() == taxonomy::SOLID || item->kind() == taxonomy::SHELL || item->kind() == taxonomy::COLLECTION || item->kind() == taxonomy::EXTRUSION || item->kind() == taxonomy::LOFT || item->kind() == taxonomy::BOOLEAN_RESULT || item->kind() == taxonomy::REVOLVE || item->kind() == taxonomy::SWEEP_ALONG_CURVE || item->kind() == taxonomy::FACE) ) { auto style = find_style(inst.as()); if (style) { auto mstyle = map(style); if (mstyle) { taxonomy::cast(item)->surface_style = taxonomy::cast(mstyle); } } } } catch (const std::exception& e) { logger_.message(ifcopenshell::logger::LOG_ERROR, "GEO", 325, std::string(e.what()) + "\nFailed to convert:", inst); } } else if (failed_on_purpose_.find(inst) == failed_on_purpose_.end()) { logger_.message(ifcopenshell::logger::LOG_ERROR, "GEO", 326, "Failed to convert:", inst); } } catch (const std::exception& e) { logger_.message(ifcopenshell::logger::LOG_ERROR, "GEO", 327, std::string(e.what()) + "\nFailed to convert:", inst); } } } IfcSchema::IfcStyledItem find_style(const IfcSchema::IfcRepresentationItem&); public: POSTFIX_SCHEMA(mapping)(ifcopenshell::file* file, ifcopenshell::geom::settings& settings, ifcopenshell::logger& logger = ifcopenshell::logger::root()) : abstract_mapping(settings, logger), file_(file), placement_rel_to_type_(nullptr) { initialize_units_(); } virtual ifcopenshell::geom::taxonomy::ptr map(const express::base&); virtual void get_representations(std::vector& tasks, std::vector& filters); virtual std::map get_layers(const express::base&); virtual void initialize_settings(); virtual double get_length_unit() const { return length_unit_; } virtual const std::string& get_length_unit_name() const { return length_unit_name_; } virtual std::vector find_openings(const express::base&); virtual express::base representation_of(const express::base& product); virtual const express::base get_product_type(const express::base& product_); virtual const express::base get_single_material_association(const express::base& product); IfcSchema::IfcRepresentation representation_mapped_to(const IfcSchema::IfcRepresentation& representation); std::vector products_represented_by(const IfcSchema::IfcRepresentation& representation, IfcSchema::IfcRepresentationMap& rmap, bool only_direct = false); bool reuse_ok_(const std::vector& products); express::base get_decomposing_entity(const express::base& product, bool include_openings); bool get_layerset_information(const express::base&, layerset_information&, int&); bool get_wall_neighbours(const express::base&, std::vector&); IfcSchema::IfcRepresentation find_representation(const IfcSchema::IfcProduct&, const std::string&); #include "bind_convert_decl.i" }; template struct element_type { typedef taxonomy::item type; }; template <> struct element_type { typedef taxonomy::geom_item type; }; template <> struct element_type { typedef taxonomy::geom_item type; }; template <> struct element_type { typedef taxonomy::face type; }; template <> struct element_type { typedef taxonomy::edge type; }; template <> struct element_type { typedef taxonomy::shell type; }; template typename U::ptr map_to_collection(POSTFIX_SCHEMA(mapping)* m, const T& ts) { auto c = taxonomy::make(); if (ts.size()) { for (auto& t : ts) { if (auto r = m->map(t)) { c->children.push_back(taxonomy::cast::type>(r)); } } } if (c->children.empty()) { #ifdef TAXONOMY_USE_NAKED_PTR delete c; #endif return nullptr; } return c; } } } #endif