diff --git a/src/ifcgeom/ConversionSettings.h b/src/ifcgeom/ConversionSettings.h index f49941ec4b..544c04ffe3 100644 --- a/src/ifcgeom/ConversionSettings.h +++ b/src/ifcgeom/ConversionSettings.h @@ -312,6 +312,12 @@ namespace ifcopenshell { static constexpr bool defaultvalue = false; }; + struct NoParallelMapping : public SettingBase { + static constexpr const char* const name = "no-parallel-mapping"; + static constexpr const char* const description = "Perform mapping upfront (single-threaded) as opposed to in parallel. May decrease performance, but also decrease output size (in the future)"; + static constexpr bool defaultvalue = false; + }; + struct ForceSpaceTransparency : public SettingBase { static constexpr const char* const name = "force-space-transparency"; static constexpr const char* const description = "Overrides transparency of spaces in geometry output."; @@ -440,7 +446,7 @@ namespace ifcopenshell { }; class IFC_GEOM_API Settings : public SettingsContainer< - std::tuple + std::tuple > {}; } diff --git a/src/ifcgeom/Iterator.h b/src/ifcgeom/Iterator.h index f4f4649b7c..8bf862def1 100644 --- a/src/ifcgeom/Iterator.h +++ b/src/ifcgeom/Iterator.h @@ -88,8 +88,15 @@ namespace { struct geometry_conversion_result { int index; + + // For NoParallelMapping==true ifcopenshell::geometry::taxonomy::ptr item; std::vector> products; + + // For NoParallelMapping==false + IfcUtil::IfcBaseEntity* representation; + aggregate_of_instance::ptr products_2; + std::vector breps; std::vector elements; }; @@ -199,20 +206,26 @@ namespace IfcGeom { for (auto& task : reps) { geometry_conversion_result res; - res.item = converter_->mapping()->map(task.representation); - if (!res.item) { - continue; + res.index = task.index; + if (!settings_.get().get()) { + res.representation = task.representation; + res.products_2 = task.products; + } else { + res.item = converter_->mapping()->map(task.representation); + if (!res.item) { + continue; + } + std::transform(task.products->begin(), task.products->end(), std::back_inserter(res.products), [this, &res](IfcUtil::IfcBaseClass* prod) { + auto prod_item = converter_->mapping()->map(prod); + return std::make_pair(prod->as(), ifcopenshell::geometry::taxonomy::cast(prod_item)->matrix); + }); } - std::transform(task.products->begin(), task.products->end(), std::back_inserter(res.products), [this, &res](IfcUtil::IfcBaseClass* prod) { - auto prod_item = converter_->mapping()->map(prod); - return std::make_pair(prod->as(), ifcopenshell::geometry::taxonomy::cast(prod_item)->matrix); - }); tasks_.push_back(res); } size_t num_products = 0; for (auto& r : tasks_) { - num_products += r.products.size(); + num_products += !settings_.get().get() ? r.products_2->size() : r.products.size(); } time_points[2] = high_resolution_clock::now(); @@ -510,7 +523,17 @@ namespace IfcGeom { ifcopenshell::geometry::Settings settings, geometry_conversion_result* rep) { - auto representation = rep->item; + if (!settings_.get().get()) { + rep->item = kernel->mapping()->map(rep->representation); + if (!rep->item) { + return; + } + std::transform(rep->products_2->begin(), rep->products_2->end(), std::back_inserter(rep->products), [this, &rep, kernel](IfcUtil::IfcBaseClass* prod) { + auto prod_item = kernel->mapping()->map(prod); + return std::make_pair(prod->as(), ifcopenshell::geometry::taxonomy::cast(prod_item)->matrix); + }); + } else { + } auto product_node = rep->products.front(); const IfcUtil::IfcBaseEntity* product = product_node.first; @@ -518,8 +541,8 @@ namespace IfcGeom { Logger::SetProduct(product); - IfcGeom::BRepElement* brep = static_cast(decorate_with_cache_(GeometrySerializer::READ_BREP, (std::string)product->get("GlobalId"), std::to_string(representation->instance->as()->id()), [kernel, settings, product, place, representation]() { - return kernel->create_brep_for_representation_and_product(representation, product, place); + IfcGeom::BRepElement* brep = static_cast(decorate_with_cache_(GeometrySerializer::READ_BREP, (std::string)product->get("GlobalId"), std::to_string(rep->item->instance->as()->id()), [kernel, settings, product, place, rep]() { + return kernel->create_brep_for_representation_and_product(rep->item, product, place); })); if (!brep) { @@ -539,7 +562,7 @@ namespace IfcGeom { const IfcUtil::IfcBaseEntity* product2 = p.first; const auto& place2 = p.second; - IfcGeom::BRepElement* brep2 = static_cast(decorate_with_cache_(GeometrySerializer::READ_BREP, (std::string)product2->get("GlobalId"), std::to_string(representation->instance->as()->id()), [kernel, settings, product2, place2, representation, brep]() { + IfcGeom::BRepElement* brep2 = static_cast(decorate_with_cache_(GeometrySerializer::READ_BREP, (std::string)product2->get("GlobalId"), std::to_string(rep->item->instance->as()->id()), [kernel, settings, product2, place2, brep]() { return kernel->create_brep_for_processed_representation(product2, place2, brep); })); if (brep2) {