mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-10 06:00:51 +00:00
Continue work on plug-in and tests
This commit is contained in:
@@ -11,7 +11,9 @@ set(SERIALIZER_RUNTIME_CPP_FILES
|
||||
set(SCHEMA_AGNOSTIC_FILES ${SCHEMA_AGNOSTIC_H_FILES} ${SCHEMA_AGNOSTIC_CPP_FILES} ${SERIALIZER_RUNTIME_CPP_FILES})
|
||||
|
||||
add_library(IfcGeom ${SCHEMA_AGNOSTIC_FILES})
|
||||
add_library(geometry ALIAS IfcGeom)
|
||||
set_target_properties(IfcGeom PROPERTIES
|
||||
OUTPUT_NAME "ifcopenshell.geometry"
|
||||
)
|
||||
set_target_properties(IfcGeom PROPERTIES COMPILE_FLAGS -DIFC_GEOM_EXPORTS)
|
||||
if (NOT CREATE_BUNDLE)
|
||||
set_target_properties(IfcGeom PROPERTIES VERSION "${PROJECT_VERSION}" SOVERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}")
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
|
||||
#include <boost/algorithm/string/case_conv.hpp>
|
||||
|
||||
#include <mutex>
|
||||
|
||||
namespace {
|
||||
std::string writer_schema_key(const std::string& schema_name) {
|
||||
return boost::to_upper_copy(schema_name);
|
||||
@@ -16,8 +14,6 @@ namespace {
|
||||
|
||||
IfcGeom::opencascade_geometry_ifc_writer_registry& IfcGeom::opencascade_geometry_ifc_writer_registry_instance() {
|
||||
static opencascade_geometry_ifc_writer_registry registry;
|
||||
static std::once_flag once;
|
||||
std::call_once(once, load_opencascade_geometry_ifc_writer_plugins, std::ref(registry));
|
||||
return registry;
|
||||
}
|
||||
|
||||
@@ -30,7 +26,11 @@ void IfcGeom::opencascade_geometry_ifc_writer_registry::bind(const std::string&
|
||||
}
|
||||
|
||||
express::Base IfcGeom::opencascade_geometry_ifc_writer_registry::tesselate(ifcopenshell::file& f, const ConversionResultShape& shape, double deflection) const {
|
||||
const auto iter = entries_.find(writer_schema_key(f.schema()->name()));
|
||||
auto iter = entries_.find(writer_schema_key(f.schema()->name()));
|
||||
if (iter == entries_.end()) {
|
||||
load_opencascade_geometry_ifc_writer_plugin(const_cast<opencascade_geometry_ifc_writer_registry&>(*this), f.schema()->name());
|
||||
iter = entries_.find(writer_schema_key(f.schema()->name()));
|
||||
}
|
||||
if (iter == entries_.end()) {
|
||||
throw ifcopenshell::exception("No geometry serialization available for " + f.schema()->name());
|
||||
}
|
||||
@@ -38,7 +38,11 @@ express::Base IfcGeom::opencascade_geometry_ifc_writer_registry::tesselate(ifcop
|
||||
}
|
||||
|
||||
express::Base IfcGeom::opencascade_geometry_ifc_writer_registry::serialise(ifcopenshell::file& f, const ConversionResultShape& shape, bool advanced) const {
|
||||
const auto iter = entries_.find(writer_schema_key(f.schema()->name()));
|
||||
auto iter = entries_.find(writer_schema_key(f.schema()->name()));
|
||||
if (iter == entries_.end()) {
|
||||
load_opencascade_geometry_ifc_writer_plugin(const_cast<opencascade_geometry_ifc_writer_registry&>(*this), f.schema()->name());
|
||||
iter = entries_.find(writer_schema_key(f.schema()->name()));
|
||||
}
|
||||
if (iter == entries_.end()) {
|
||||
throw ifcopenshell::exception("No geometry serialization available for " + f.schema()->name());
|
||||
}
|
||||
|
||||
@@ -55,3 +55,25 @@ void IfcGeom::load_opencascade_geometry_ifc_writer_plugins(opencascade_geometry_
|
||||
register_plugin(registry, module);
|
||||
}
|
||||
}
|
||||
|
||||
bool IfcGeom::load_opencascade_geometry_ifc_writer_plugin(opencascade_geometry_ifc_writer_registry& registry, const std::string& schema_name) {
|
||||
ifcopenshell::plugin::manager manager;
|
||||
manager.add_search_path(opencascade_geometry_ifc_writer_plugin_directory());
|
||||
|
||||
const auto expected_schema = boost::to_upper_copy(schema_name);
|
||||
const auto basename = std::string(opencascade_geometry_ifc_writer_plugin_prefix) + boost::to_lower_copy(schema_name);
|
||||
|
||||
for (const auto& path : manager.discover_exact(basename)) {
|
||||
auto module = manager.load(path);
|
||||
if (module.meta().kind_ != ifcopenshell::plugin::kind::opencascade_geometry_ifc_writer ||
|
||||
module.meta().schema != expected_schema) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto register_plugin = module.get_alias<register_opencascade_geometry_ifc_writer_plugin_fn>(opencascade_geometry_ifc_writer_plugin_registration_symbol());
|
||||
register_plugin(registry, module);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ IFC_GEOMSERIALIZATION_API const char* opencascade_geometry_ifc_writer_plugin_reg
|
||||
IFC_GEOMSERIALIZATION_API ifcopenshell::plugin::metadata opencascade_geometry_ifc_writer_plugin_metadata(const std::string& schema_name);
|
||||
IFC_GEOMSERIALIZATION_API std::filesystem::path opencascade_geometry_ifc_writer_plugin_directory();
|
||||
IFC_GEOMSERIALIZATION_API void load_opencascade_geometry_ifc_writer_plugins(opencascade_geometry_ifc_writer_registry& registry);
|
||||
IFC_GEOMSERIALIZATION_API bool load_opencascade_geometry_ifc_writer_plugin(opencascade_geometry_ifc_writer_registry& registry, const std::string& schema_name);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -2,10 +2,10 @@ if (NOT WASM_BUILD)
|
||||
|
||||
foreach(schema ${SCHEMA_VERSIONS})
|
||||
add_library(geometry_serializer_ifc${schema} SHARED Serialization.cpp plugin.cpp)
|
||||
target_link_libraries(geometry_serializer_ifc${schema} PRIVATE plugin geometry_serializer IfcGeom IfcParse ${OpenCASCADE_LIBRARIES})
|
||||
target_link_libraries(geometry_serializer_ifc${schema} PRIVATE plugin geometry_serializer IfcGeom IfcParse parse_schema_ifc${schema} ${OpenCASCADE_LIBRARIES})
|
||||
set_target_properties(geometry_serializer_ifc${schema} PROPERTIES
|
||||
COMPILE_FLAGS "-DIfcSchema=Ifc${schema}"
|
||||
OUTPUT_NAME "geometry.serialization.ifc${schema}"
|
||||
OUTPUT_NAME "ifcopenshell.geometry.serialization.ifc${schema}"
|
||||
RUNTIME_OUTPUT_DIRECTORY "${geometry_serialization_plugin_runtime_dir}"
|
||||
LIBRARY_OUTPUT_DIRECTORY "${geometry_serialization_plugin_runtime_dir}"
|
||||
)
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
#include "../ifcgeom/mapping_plugin.h"
|
||||
|
||||
#include <boost/algorithm/string/case_conv.hpp>
|
||||
#include <mutex>
|
||||
|
||||
namespace {
|
||||
std::string mapping_key(const std::string& schema_name) {
|
||||
@@ -15,8 +14,6 @@ namespace {
|
||||
|
||||
ifcopenshell::geometry::impl::mapping_registry& ifcopenshell::geometry::impl::mapping_registry_instance() {
|
||||
static mapping_registry registry;
|
||||
static std::once_flag once;
|
||||
std::call_once(once, load_mapping_plugins, std::ref(registry));
|
||||
return registry;
|
||||
}
|
||||
|
||||
@@ -28,7 +25,11 @@ void ifcopenshell::geometry::impl::mapping_registry::bind(const std::string& sch
|
||||
|
||||
ifcopenshell::geometry::abstract_mapping* ifcopenshell::geometry::impl::mapping_registry::construct(ifcopenshell::file* file, Settings& s) {
|
||||
const std::string schema_name_lower = boost::to_lower_copy(file->schema()->name());
|
||||
const auto it = entries_.find(schema_name_lower);
|
||||
auto it = entries_.find(schema_name_lower);
|
||||
if (it == entries_.end()) {
|
||||
load_mapping_plugin(*this, file->schema()->name());
|
||||
it = entries_.find(schema_name_lower);
|
||||
}
|
||||
if (it == entries_.end()) {
|
||||
throw ifcopenshell::exception("No geometry mapping registered for " + schema_name_lower);
|
||||
}
|
||||
|
||||
@@ -19,10 +19,19 @@
|
||||
|
||||
#include "kernel_plugin.h"
|
||||
|
||||
#include <boost/algorithm/string/case_conv.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace {
|
||||
constexpr const char* kernel_plugin_prefix = "geometry.kernel.";
|
||||
|
||||
std::string kernel_plugin_name(const std::string& backend_id) {
|
||||
auto name = boost::to_lower_copy(backend_id);
|
||||
name.erase(std::remove(name.begin(), name.end(), '-'), name.end());
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
const char* ifcopenshell::geometry::kernels::kernel_plugin_registration_symbol() {
|
||||
@@ -54,3 +63,25 @@ void ifcopenshell::geometry::kernels::load_kernel_plugins(kernel_registry& regis
|
||||
register_plugin(registry, module);
|
||||
}
|
||||
}
|
||||
|
||||
bool ifcopenshell::geometry::kernels::load_kernel_plugin(kernel_registry& registry, const std::string& backend_id) {
|
||||
plugin::manager manager;
|
||||
manager.add_search_path(kernel_plugin_directory());
|
||||
|
||||
const auto plugin_name = kernel_plugin_name(backend_id);
|
||||
const auto basename = std::string(kernel_plugin_prefix) + plugin_name;
|
||||
|
||||
for (const auto& path : manager.discover_exact(basename)) {
|
||||
auto module = manager.load(path);
|
||||
if (module.meta().kind_ != plugin::kind::kernel ||
|
||||
module.meta().id != basename) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto register_plugin = module.get_alias<register_kernel_plugin_fn>(kernel_plugin_registration_symbol());
|
||||
register_plugin(registry, module);
|
||||
return registry.has(backend_id);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ namespace ifcopenshell {
|
||||
IFC_GEOM_API ifcopenshell::plugin::metadata kernel_plugin_metadata(const std::string& plugin_name);
|
||||
IFC_GEOM_API std::filesystem::path kernel_plugin_directory();
|
||||
IFC_GEOM_API void load_kernel_plugins(kernel_registry& registry);
|
||||
IFC_GEOM_API bool load_kernel_plugin(kernel_registry& registry, const std::string& backend_id);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,8 +25,9 @@
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
|
||||
namespace {
|
||||
std::string kernel_key(const std::string& backend_id) {
|
||||
@@ -65,8 +66,6 @@ std::vector<ifcopenshell::geometry::kernels::kernel_info> ifcopenshell::geometry
|
||||
|
||||
ifcopenshell::geometry::kernels::kernel_registry& ifcopenshell::geometry::kernels::kernel_registry_instance() {
|
||||
static kernel_registry registry;
|
||||
static std::once_flag once;
|
||||
std::call_once(once, load_kernel_plugins, std::ref(registry));
|
||||
return registry;
|
||||
}
|
||||
|
||||
@@ -74,6 +73,9 @@ std::unique_ptr<ifcopenshell::geometry::kernels::AbstractKernel> ifcopenshell::g
|
||||
auto geometry_library_lower = boost::to_lower_copy(geometry_library);
|
||||
auto& registry = kernel_registry_instance();
|
||||
|
||||
if (!registry.has(geometry_library_lower)) {
|
||||
load_kernel_plugin(registry, geometry_library_lower);
|
||||
}
|
||||
if (registry.has(geometry_library_lower)) {
|
||||
return registry.create(geometry_library_lower, file, settings);
|
||||
}
|
||||
@@ -88,6 +90,20 @@ std::unique_ptr<ifcopenshell::geometry::kernels::AbstractKernel> ifcopenshell::g
|
||||
throw ifcopenshell::exception("Invalid hybrid kernel " + geometry_library);
|
||||
}
|
||||
|
||||
std::vector<std::string> candidates;
|
||||
candidates.push_back(geometry_library_lower);
|
||||
for (auto pos = geometry_library_lower.find('-'); pos != std::string::npos; pos = geometry_library_lower.find('-', pos + 1)) {
|
||||
candidates.push_back(geometry_library_lower.substr(0, pos));
|
||||
}
|
||||
std::sort(candidates.begin(), candidates.end(), [](const auto& a, const auto& b) {
|
||||
return a.size() > b.size();
|
||||
});
|
||||
for (const auto& candidate : candidates) {
|
||||
if (!registry.has(candidate) && load_kernel_plugin(registry, candidate)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::string matched_backend_id;
|
||||
for (const auto& info : registry.kernels()) {
|
||||
const auto backend_id = kernel_key(info.backend_id);
|
||||
|
||||
@@ -31,7 +31,7 @@ foreach(kernel ${GEOMETRY_KERNELS})
|
||||
|
||||
set_target_properties(${KERNEL_TARGET} PROPERTIES
|
||||
COMPILE_FLAGS "-DIFC_GEOMLIBRARY_EXPORTS"
|
||||
OUTPUT_NAME "geometry.kernel.${kernel}"
|
||||
OUTPUT_NAME "ifcopenshell.geometry.kernel.${kernel}"
|
||||
RUNTIME_OUTPUT_DIRECTORY "${kernel_plugin_runtime_dir}"
|
||||
LIBRARY_OUTPUT_DIRECTORY "${kernel_plugin_runtime_dir}"
|
||||
)
|
||||
@@ -50,7 +50,7 @@ foreach(kernel ${GEOMETRY_KERNELS})
|
||||
|
||||
set_target_properties(${KERNEL_TARGET_SIMPLE} PROPERTIES
|
||||
COMPILE_FLAGS "-DIFC_GEOMLIBRARY_EXPORTS -DIFOPSH_SIMPLE_KERNEL -DCGAL_HAS_THREADS"
|
||||
OUTPUT_NAME "geometry.kernel.cgalsimple"
|
||||
OUTPUT_NAME "ifcopenshell.geometry.kernel.cgalsimple"
|
||||
RUNTIME_OUTPUT_DIRECTORY "${kernel_plugin_runtime_dir}"
|
||||
LIBRARY_OUTPUT_DIRECTORY "${kernel_plugin_runtime_dir}"
|
||||
)
|
||||
@@ -76,7 +76,7 @@ foreach(kernel ${GEOMETRY_KERNELS})
|
||||
)
|
||||
set_target_properties(${TREE_TARGET} PROPERTIES
|
||||
COMPILE_FLAGS "-DIFC_GEOMLIBRARY_EXPORTS"
|
||||
OUTPUT_NAME "geometry.tree.opencascade.${tree_backend}"
|
||||
OUTPUT_NAME "ifcopenshell.geometry.tree.opencascade.${tree_backend}"
|
||||
RUNTIME_OUTPUT_DIRECTORY "${kernel_plugin_runtime_dir}"
|
||||
LIBRARY_OUTPUT_DIRECTORY "${kernel_plugin_runtime_dir}"
|
||||
)
|
||||
|
||||
@@ -17,14 +17,23 @@ foreach(schema ${SCHEMA_VERSIONS})
|
||||
add_library(geometry_mapping_ifc${schema} SHARED ${IFCGEOM_FILES})
|
||||
set_target_properties(geometry_mapping_ifc${schema} PROPERTIES
|
||||
COMPILE_FLAGS "-DIfcSchema=Ifc${schema}"
|
||||
OUTPUT_NAME "geometry.mapping.ifc${schema}"
|
||||
OUTPUT_NAME "ifcopenshell.geometry.mapping.ifc${schema}"
|
||||
RUNTIME_OUTPUT_DIRECTORY "${mapping_plugin_runtime_dir}"
|
||||
LIBRARY_OUTPUT_DIRECTORY "${mapping_plugin_runtime_dir}"
|
||||
)
|
||||
|
||||
ifcopenshell_wasm_plugin_link_options(geometry_mapping_ifc${schema} ifcopenshell_register_mapping_plugin_v1)
|
||||
if(WASM_BUILD)
|
||||
target_link_options(geometry_mapping_ifc${schema} PRIVATE "SHELL:-s ERROR_ON_UNDEFINED_SYMBOLS=0")
|
||||
endif()
|
||||
|
||||
target_link_libraries(geometry_mapping_ifc${schema} PRIVATE ${plugin_when_not_wasm} IfcGeom IfcParse Eigen3::Eigen)
|
||||
if(NOT WASM_BUILD)
|
||||
set(schema_plugin_library parse_schema_ifc${schema})
|
||||
else()
|
||||
set(schema_plugin_library)
|
||||
endif()
|
||||
|
||||
target_link_libraries(geometry_mapping_ifc${schema} PRIVATE ${plugin_when_not_wasm} IfcGeom IfcParse ${schema_plugin_library} Eigen3::Eigen)
|
||||
|
||||
list(APPEND mapping_libraries geometry_mapping_ifc${schema})
|
||||
|
||||
|
||||
@@ -55,3 +55,25 @@ void ifcopenshell::geometry::impl::load_mapping_plugins(mapping_registry& regist
|
||||
register_plugin(registry, module);
|
||||
}
|
||||
}
|
||||
|
||||
bool ifcopenshell::geometry::impl::load_mapping_plugin(mapping_registry& registry, const std::string& schema_name) {
|
||||
plugin::manager manager;
|
||||
manager.add_search_path(mapping_plugin_directory());
|
||||
|
||||
const auto expected_schema = boost::to_upper_copy(schema_name);
|
||||
const auto basename = std::string(mapping_plugin_prefix) + boost::to_lower_copy(schema_name);
|
||||
|
||||
for (const auto& path : manager.discover_exact(basename)) {
|
||||
auto module = manager.load(path);
|
||||
if (module.meta().kind_ != plugin::kind::mapping ||
|
||||
module.meta().schema != expected_schema) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto register_plugin = module.get_alias<register_mapping_plugin_fn>(mapping_plugin_registration_symbol());
|
||||
register_plugin(registry, module);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ namespace ifcopenshell {
|
||||
IFC_GEOM_API ifcopenshell::plugin::metadata mapping_plugin_metadata(const std::string& schema_name);
|
||||
IFC_GEOM_API std::filesystem::path mapping_plugin_directory();
|
||||
IFC_GEOM_API void load_mapping_plugins(mapping_registry& registry);
|
||||
IFC_GEOM_API bool load_mapping_plugin(mapping_registry& registry, const std::string& schema_name);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
|
||||
#include "tree_plugin.h"
|
||||
|
||||
#include <boost/algorithm/string/case_conv.hpp>
|
||||
|
||||
namespace {
|
||||
constexpr const char* tree_plugin_prefix = "geometry.tree.";
|
||||
}
|
||||
@@ -52,3 +54,25 @@ void ifcopenshell::geometry::trees::load_tree_plugins(tree_registry& registry) {
|
||||
register_plugin(registry, module);
|
||||
}
|
||||
}
|
||||
|
||||
bool ifcopenshell::geometry::trees::load_tree_plugin(tree_registry& registry, const std::string& backend_id) {
|
||||
plugin::manager manager;
|
||||
manager.add_search_path(tree_plugin_directory());
|
||||
|
||||
const auto plugin_name = boost::to_lower_copy(backend_id);
|
||||
const auto basename = std::string(tree_plugin_prefix) + plugin_name;
|
||||
|
||||
for (const auto& path : manager.discover_exact(basename)) {
|
||||
auto module = manager.load(path);
|
||||
if (module.meta().kind_ != plugin::kind::tree ||
|
||||
module.meta().id != basename) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto register_plugin = module.get_alias<register_tree_plugin_fn>(tree_plugin_registration_symbol());
|
||||
register_plugin(registry, module);
|
||||
return registry.has(backend_id);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ namespace ifcopenshell {
|
||||
IFC_GEOM_API ifcopenshell::plugin::metadata tree_plugin_metadata(const std::string& plugin_name);
|
||||
IFC_GEOM_API std::filesystem::path tree_plugin_directory();
|
||||
IFC_GEOM_API void load_tree_plugins(tree_registry& registry);
|
||||
IFC_GEOM_API bool load_tree_plugin(tree_registry& registry, const std::string& backend_id);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,8 +24,6 @@
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
#include <mutex>
|
||||
|
||||
namespace {
|
||||
std::string tree_key(const std::string& backend_id) {
|
||||
return boost::to_lower_copy(backend_id);
|
||||
@@ -134,11 +132,13 @@ std::unique_ptr<ifcopenshell::geometry::trees::abstract_tree> ifcopenshell::geom
|
||||
|
||||
ifcopenshell::geometry::trees::tree_registry& ifcopenshell::geometry::trees::tree_registry_instance() {
|
||||
static tree_registry registry;
|
||||
static std::once_flag once;
|
||||
std::call_once(once, load_tree_plugins, std::ref(registry));
|
||||
return registry;
|
||||
}
|
||||
|
||||
std::unique_ptr<ifcopenshell::geometry::trees::abstract_tree> ifcopenshell::geometry::trees::construct(const std::string& backend_id) {
|
||||
return tree_registry_instance().create(backend_id);
|
||||
auto& registry = tree_registry_instance();
|
||||
if (!registry.has(backend_id)) {
|
||||
load_tree_plugin(registry, backend_id);
|
||||
}
|
||||
return registry.create(backend_id);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user