Continue work on plug-in and tests

This commit is contained in:
Thomas Krijnen
2026-05-06 21:17:25 +02:00
parent 4670715ef3
commit 98ff457fd6
61 changed files with 16000 additions and 16377 deletions
-7
View File
@@ -441,13 +441,6 @@ endif()
message(STATUS "IFC SCHEMA_VERSIONS that will be used for the build: ${SCHEMA_VERSIONS}.")
foreach(schema ${SCHEMA_VERSIONS})
add_definitions(-DHAS_SCHEMA_${schema})
endforeach()
string(REPLACE ";" ")(" schema_version_seq "(${SCHEMA_VERSIONS})")
add_definitions(-DSCHEMA_SEQ=${schema_version_seq})
if(COMPILE_SCHEMA)
# @todo, this appears to be untested at the moment
find_package(PythonInterp)
+20 -13
View File
@@ -53,27 +53,34 @@ macro(build_example exe_name)
install(TARGETS ${exe_name})
endmacro()
macro(build_schema_example exe_name schema)
build_example(${exe_name} ${ARGN})
if(NOT STANDALONE_PROJECT)
target_link_libraries(${exe_name} parse_schema_ifc${schema})
endif()
endmacro()
if("4" IN_LIST SCHEMA_VERSIONS)
build_example(arbitrary_open_profile_def)
build_example(triangulated_faceset)
build_schema_example(arbitrary_open_profile_def 4)
build_schema_example(triangulated_faceset 4)
endif()
if("2x3" IN_LIST SCHEMA_VERSIONS)
build_example(composite_profile_def)
build_example(csg_primitive)
build_example(ellipse_pies)
build_example(faces)
build_example(ifc_curve_rebar)
build_example(profiles)
build_example(IfcParseExamples)
build_schema_example(composite_profile_def 2x3)
build_schema_example(csg_primitive 2x3)
build_schema_example(ellipse_pies 2x3)
build_schema_example(faces 2x3)
build_schema_example(ifc_curve_rebar 2x3)
build_schema_example(profiles 2x3)
build_schema_example(IfcParseExamples 2x3)
if(WITH_OPENCASCADE)
build_example(IfcOpenHouse geometry_serializer)
build_example(IfcAdvancedHouse geometry_serializer)
build_schema_example(IfcOpenHouse 2x3 geometry_serializer)
build_schema_example(IfcAdvancedHouse 2x3 geometry_serializer)
endif()
endif()
if("4x3_add2" IN_LIST SCHEMA_VERSIONS)
build_example(IfcAlignment)
build_example(IfcSimplifiedAlignment)
build_schema_example(IfcAlignment 4x3_add2)
build_schema_example(IfcSimplifiedAlignment 4x3_add2)
endif()
+3 -49
View File
@@ -24,48 +24,10 @@
#include "../ifcparse/logger.h"
#include "../ifcparse/schemas/Ifc2x3.h"
#include <boost/preprocessor/stringize.hpp>
#include <boost/preprocessor/seq/for_each.hpp>
#include <boost/preprocessor/seq/size.hpp>
#include <boost/preprocessor/seq/pop_back.hpp>
#include <boost/preprocessor/comparison/greater.hpp>
#include <boost/preprocessor/selection/min.hpp>
#ifdef _MSC_VER
#define strcasecmp _stricmp
#endif
#ifndef SCHEMA_SEQ
static_assert(false, "A boost preprocessor sequence of schema identifiers is needed for this file to compile.");
#endif
// @todo duplicated with Kernel.h
// @tfk A macro cannot define an include (I think), so here we can't
// loop over the sequence of schema identifiers, but rather we have
// unroll the loop with at least the amount of schemas we'd like support
// for and then overflow into an existing empty include file.
#define INCLUDE_SCHEMA(n) \
BOOST_PP_IIF(BOOST_PP_GREATER(BOOST_PP_SEQ_SIZE(SCHEMA_SEQ), n), BOOST_PP_STRINGIZE(../ifcparse/schemas/BOOST_PP_CAT(Ifc,BOOST_PP_SEQ_ELEM(BOOST_PP_MIN(n, BOOST_PP_SEQ_SIZE(BOOST_PP_SEQ_POP_BACK(SCHEMA_SEQ))),SCHEMA_SEQ)).h), "../ifcgeom/empty.h")
#include INCLUDE_SCHEMA(0)
#include INCLUDE_SCHEMA(1)
#include INCLUDE_SCHEMA(2)
#include INCLUDE_SCHEMA(3)
#include INCLUDE_SCHEMA(4)
#include INCLUDE_SCHEMA(5)
#include INCLUDE_SCHEMA(6)
#include INCLUDE_SCHEMA(7)
#include INCLUDE_SCHEMA(8)
#include INCLUDE_SCHEMA(9)
#include INCLUDE_SCHEMA(10)
#include INCLUDE_SCHEMA(11)
#include INCLUDE_SCHEMA(12)
#include INCLUDE_SCHEMA(13)
#include INCLUDE_SCHEMA(14)
#include INCLUDE_SCHEMA(15)
#include <iomanip>
#if USE_VLD
@@ -205,19 +167,11 @@ void get_psets_s(element_properties& props, const typename Schema::IfcObjectDefi
}
}
// What follows is machinery to create a preprocessor-based dispatch mechanism to dispatch to the
// correct get_psets_s<Schema>() based on inst->declaration().schema()->name().
#define EXPAND_AND_CONCATENATE(elem) Ifc##elem
#define GENERATE_LITERAL_STRING(elem) "Ifc" # elem
#define TEST_AND_DISPATCH(r, data, elem) \
if (strcasecmp(schema_name, GENERATE_LITERAL_STRING(elem)) == 0) { get_psets_s<EXPAND_AND_CONCATENATE(elem)>(props, inst.as<EXPAND_AND_CONCATENATE(elem)::IfcObjectDefinition>()); }
void get_psets(element_properties& props, const express::Base& inst) {
auto schema_name = inst.declaration().schema()->name().c_str();
BOOST_PP_SEQ_FOR_EACH(TEST_AND_DISPATCH, , SCHEMA_SEQ)
if (strcasecmp(schema_name, "Ifc2x3") == 0) {
get_psets_s<Ifc2x3>(props, inst.as<Ifc2x3::IfcObjectDefinition>());
}
}
int main(int argc, char** argv) {
+3 -2
View File
@@ -2,11 +2,12 @@
add_executable(IfcConvert IfcConvert.cpp)
target_link_libraries(IfcConvert PRIVATE IfcGeom IfcParse ${Boost_LIBRARIES})
if(kernel_libraries OR mapping_libraries OR geometry_serializer_libraries OR document_serializer_libraries)
add_dependencies(IfcConvert ${kernel_libraries} ${mapping_libraries} ${geometry_serializer_libraries} ${document_serializer_libraries})
if(schema_libraries OR kernel_libraries OR mapping_libraries OR geometry_serializer_libraries OR document_serializer_libraries)
add_dependencies(IfcConvert ${schema_libraries} ${kernel_libraries} ${mapping_libraries} ${geometry_serializer_libraries} ${document_serializer_libraries})
endif()
set(_plugin_targets
${schema_libraries}
${kernel_libraries}
${mapping_libraries}
${geometry_serializer_libraries}
+14 -4
View File
@@ -285,7 +285,7 @@ int main(int argc, char** argv) {
auto& document_serializer_registry = ifcopenshell::serializers::document_serializer_registry_instance();
auto& geometry_serializer_registry = ifcopenshell::serializers::geometry_serializer_registry_instance();
#ifdef WITH_HDF5
const bool supports_geometry_cache = geometry_serializer_registry.has(".h5");
const bool supports_geometry_cache = true;
#else
const bool supports_geometry_cache = false;
#endif
@@ -603,8 +603,7 @@ int main(int argc, char** argv) {
const path_t IFC = ifcopenshell::path::from_utf8(".ifc");
const auto* document_serializer_info = document_serializer_registry.find(output_extension_utf8);
if (document_serializer_info) {
auto run_document_serializer = [&](const ifcopenshell::serializers::document_serializer_info* document_serializer_info) {
int exit_code = EXIT_FAILURE;
try {
const bool use_input_filename = vmap.count("stream") && document_serializer_info->supports_input_filename;
@@ -612,7 +611,7 @@ int main(int argc, char** argv) {
throw ifcopenshell::exception("Selected document serializer requires --stream");
}
if (use_input_filename || init_input_file(ifcopenshell::path::to_utf8(input_filename), ifc_file, no_progress || quiet, mmap)) {
if (use_input_filename || ifc_file || init_input_file(ifcopenshell::path::to_utf8(input_filename), ifc_file, no_progress || quiet, mmap)) {
if (!use_input_filename) {
document_serializer_info = document_serializer_registry.find(output_extension_utf8, ifc_file->schema()->name());
if (!document_serializer_info) {
@@ -651,6 +650,11 @@ int main(int argc, char** argv) {
}
write_log(!quiet);
return exit_code;
};
const auto* document_serializer_info = document_serializer_registry.find(output_extension_utf8);
if (document_serializer_info) {
return run_document_serializer(document_serializer_info);
} else if (output_extension == IFC) {
int exit_code = EXIT_FAILURE;
try {
@@ -679,6 +683,12 @@ int main(int argc, char** argv) {
const auto* geometry_serializer_info = geometry_serializer_registry.find(output_extension_utf8);
if (!geometry_serializer_info) {
if (init_input_file(ifcopenshell::path::to_utf8(input_filename), ifc_file, no_progress || quiet, mmap)) {
document_serializer_info = document_serializer_registry.find(output_extension_utf8, ifc_file->schema()->name());
if (document_serializer_info) {
return run_document_serializer(document_serializer_info);
}
}
cerr_ << "[error] Unknown output filename extension '" << output_extension << "'\n";
write_log(!quiet);
print_usage();
+3 -1
View File
@@ -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}")
+10 -6
View File
@@ -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}"
)
+5 -4
View File
@@ -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);
}
+31
View File
@@ -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;
}
+1
View File
@@ -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);
}
}
+19 -3
View File
@@ -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);
+3 -3
View File
@@ -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}"
)
+11 -2
View File
@@ -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})
+22
View File
@@ -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;
}
+1
View File
@@ -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);
}
}
+24
View File
@@ -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;
}
+1
View File
@@ -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);
}
}
+5 -5
View File
@@ -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);
}
+2 -2
View File
@@ -7,8 +7,8 @@ target_link_libraries(IfcGeomServer IfcGeom ${OpenCASCADE_LIBRARIES})
if(WITH_OPENCASCADE)
target_link_libraries(IfcGeomServer geometry_kernel_opencascade)
endif()
if(kernel_libraries OR mapping_libraries)
add_dependencies(IfcGeomServer ${kernel_libraries} ${mapping_libraries})
if(schema_libraries OR kernel_libraries OR mapping_libraries)
add_dependencies(IfcGeomServer ${schema_libraries} ${kernel_libraries} ${mapping_libraries})
endif()
install(TARGETS IfcGeomServer EXPORT ${IFCOPENSHELL_EXPORT_TARGETS})
@@ -39,9 +39,9 @@ class spf_header;
struct %(schema_name)s {
IFC_PARSE_API static const ifcopenshell::schema_definition& get_schema();
IFC_SCHEMA_API static const ifcopenshell::schema_definition& get_schema();
IFC_PARSE_API static void clear_schema();
IFC_SCHEMA_API static void clear_schema();
static const char* const Identifier;
@@ -111,7 +111,7 @@ derived_field_statement = " {std::set<int> idxs; %(statements)sderived_map[Ty
derived_field_statement_attrs = "idxs.insert(%d); "
simpletype = """%(documentation)s
class IFC_PARSE_API %(name)s : public %(superclass)s {
class IFC_SCHEMA_API %(name)s : public %(superclass)s {
public:
using %(superclass)s::%(superclass_2)s;
@@ -139,7 +139,7 @@ simpletype_impl_cast_templated = "std::vector<express::Base> es = get_attribute_
simpletype_impl_declaration = "return *((ifcopenshell::type_declaration*)%(schema_name_upper)s_types[%(index_in_schema)d]);"
select = """%(documentation)s
class IFC_PARSE_API %(name)s : public express::Select {
class IFC_SCHEMA_API %(name)s : public express::Select {
public:
using express::Select::Select;
@@ -158,7 +158,7 @@ select_cast_function = """ %(name)s(const %(item_name)s& c) : express::Select
"""
enumeration = """%(documentation)s
class IFC_PARSE_API %(name)s : public express::DeclaredType {
class IFC_SCHEMA_API %(name)s : public express::DeclaredType {
public:
using express::DeclaredType::DeclaredType;
@@ -174,7 +174,7 @@ public:
"""
entity = """%(documentation)s
class IFC_PARSE_API %(name)s : public %(superclass)s {
class IFC_SCHEMA_API %(name)s : public %(superclass)s {
public:
using %(superclass)s::%(superclass_2)s;
+1 -1
View File
@@ -718,7 +718,7 @@ class file_mixin:
"""
if self.transaction:
max_id = self.getMaxId()
max_id = self.get_max_id()
result = self._add(inst, -1 if _id is None else _id)
@@ -1675,14 +1675,14 @@ def remove_deep2(
subgraph = list(ifc_file.traverse(element, breadth_first=True))
subgraph.extend(also_consider)
subgraph_set = set(subgraph)
subelement_queue = deque([element])
subelement_queue = [element]
# Cache already processed entities to avoid traversing them multiple time.
# E.g. lots of IFCINDEXEDPOLYCURVES may reference the same IFCCARTESIANPOINTLIST2D.
processed_ids: set[int] = set()
while subelement_queue:
subelement = subelement_queue.popleft()
subelement = subelement_queue.pop(0)
subelement_id = subelement.id()
if (
subelement_id
@@ -16,10 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
import ifcopenshell
import pytest
import test.bootstrap
class TestGetInfo2(test.bootstrap.IFC4):
def test_instance_attribute(self):
brep = self.file.create_entity("IfcFacetedBrep")
@@ -14,6 +14,7 @@ import ifcopenshell.guid
import ifcopenshell.template
@pytest.mark.skip(reason="Current file retention is not automatic anymore if a single instance is alive")
@pytest.mark.parametrize(
"args",
itertools.product((0, 1), (0, 1), (0, 1), (0, 1, 2)),
+45 -6
View File
@@ -11,16 +11,17 @@ foreach(file ${IFCPARSE_CPP_FILES_ALL})
list(APPEND IFCPARSE_CPP_FILES "${file}")
endforeach()
list(REMOVE_ITEM IFCPARSE_CPP_FILES
${CMAKE_CURRENT_SOURCE_DIR}/schema_plugin.cpp
${CMAKE_CURRENT_SOURCE_DIR}/alignment_helper.cpp
)
message(STATUS "SCHEMA_VERSIONS from ifcparse: ${SCHEMA_VERSIONS}")
foreach(schema ${SCHEMA_VERSIONS})
list(APPEND IFCPARSE_H_FILES
schemas/Ifc${schema}.h
schemas/Ifc${schema}-definitions.h
)
list(APPEND IFCPARSE_CPP_FILES
schemas/Ifc${schema}.cpp
schemas/Ifc${schema}-schema.cpp
)
endforeach()
list(APPEND IFCPARSE_H_FILES
@@ -34,7 +35,9 @@ list(APPEND IFCPARSE_CPP_FILES
set(IFCPARSE_FILES ${IFCPARSE_CPP_FILES} ${IFCPARSE_H_FILES})
add_library(IfcParse ${IFCPARSE_FILES})
add_library(parse ALIAS IfcParse)
set_target_properties(IfcParse PROPERTIES
OUTPUT_NAME "ifcopenshell.parse"
)
target_compile_definitions(IfcParse PUBLIC ${SCHEMA_DEFINITIONS})
if(USE_MMAP)
target_compile_definitions(IfcParse PUBLIC USE_MMAP)
@@ -60,9 +63,45 @@ if(WITH_ROCKSDB)
endif()
endif()
if (NOT WASM_BUILD)
set(plugin_when_not_wasm plugin)
endif()
foreach(schema ${SCHEMA_VERSIONS})
set(SCHEMA_PLUGIN_TARGET parse_schema_ifc${schema})
set(SCHEMA_PLUGIN_SOURCES
schema_plugin.cpp
hierarchy_helper.i
schemas/Ifc${schema}.cpp
schemas/Ifc${schema}-schema.cpp
)
if(schema STREQUAL "4x3_add2")
list(APPEND SCHEMA_PLUGIN_SOURCES alignment_helper.cpp)
endif()
add_library(${SCHEMA_PLUGIN_TARGET} SHARED ${SCHEMA_PLUGIN_SOURCES})
target_compile_definitions(${SCHEMA_PLUGIN_TARGET} PRIVATE
IFC_SCHEMA_EXPORTS
BOOST_DLL_USE_STD_FS
IfcSchema=Ifc${schema}
)
target_link_libraries(${SCHEMA_PLUGIN_TARGET} PRIVATE ${plugin_when_not_wasm} IfcParse)
set_target_properties(${SCHEMA_PLUGIN_TARGET} PROPERTIES
OUTPUT_NAME "ifcopenshell.parse.schema.ifc${schema}"
)
if(WASM_BUILD)
target_link_options(${SCHEMA_PLUGIN_TARGET} PRIVATE "SHELL:-s SIDE_MODULE=1")
endif()
list(APPEND schema_libraries ${SCHEMA_PLUGIN_TARGET})
endforeach()
# CMake installation targets
install(FILES ${IFCPARSE_H_FILES}
DESTINATION ${INCLUDEDIR}/ifcparse
)
install(TARGETS IfcParse)
install(TARGETS IfcParse ${schema_libraries})
set(schema_libraries ${schema_libraries} PARENT_SCOPE)
-3
View File
@@ -32,8 +32,6 @@ static const double PI = boost::math::constants::pi<double>();
#include <boost/math/quadrature/trapezoidal.hpp>
#ifdef HAS_SCHEMA_4x3_add2
// sets the segment name like ("H1" for horizontal, "V1" for vertical, "C1" for cant)
void _name_segments(const char* prefix, std::vector<Ifc4x3_add2::IfcObjectDefinition>& segments) {
unsigned idx = 1;
@@ -886,4 +884,3 @@ std::pair<Ifc4x3_add2::IfcCurveSegment, Ifc4x3_add2::IfcCurveSegment> mapAlignme
}
return result;
}
#endif
+7 -12
View File
@@ -29,31 +29,26 @@
#include "ifc_parse_api.h"
#include "logger.h"
#ifdef HAS_SCHEMA_4x3_add2
#include "schemas/Ifc4x3_add2.h"
#endif
#include "hierarchy_helper.h"
#include "schemas/Ifc4x3_add2.h"
#ifdef HAS_SCHEMA_4x3_add2
//
// alignment helper methods
//
// creates a horizontal alignment from a list of PI points and curve radii. if include_geometry is true, the geometric representations are created, otherwise only business logic is created
IFC_PARSE_API Ifc4x3_add2::IfcAlignment addHorizontalAlignment(hierarchy_helper<Ifc4x3_add2>& model, const std::string& alignment_name, const std::vector<std::pair<double, double>>& points, const std::vector<double>& radii, bool include_geometry = true);
IFC_SCHEMA_API Ifc4x3_add2::IfcAlignment addHorizontalAlignment(hierarchy_helper<Ifc4x3_add2>& model, const std::string& alignment_name, const std::vector<std::pair<double, double>>& points, const std::vector<double>& radii, bool include_geometry = true);
// creates a horizontal and vertical alignment from a list of PI points, curve radii, and VPI points and vertical curve lengths. if include_geometry is true, the geometric representations are created, otherwise only business logic is created
IFC_PARSE_API Ifc4x3_add2::IfcAlignment addAlignment(hierarchy_helper<Ifc4x3_add2>& model, const std::string& alignment_name, const std::vector<std::pair<double, double>>& points, const std::vector<double>& radii, const std::vector<std::pair<double, double>>& vertical_points, const std::vector<double>& vertical_curve_lengths, bool include_geometry = true);
IFC_SCHEMA_API Ifc4x3_add2::IfcAlignment addAlignment(hierarchy_helper<Ifc4x3_add2>& model, const std::string& alignment_name, const std::vector<std::pair<double, double>>& points, const std::vector<double>& radii, const std::vector<std::pair<double, double>>& vertical_points, const std::vector<double>& vertical_curve_lengths, bool include_geometry = true);
// Maps horizontal alignment business logic to geometry.
// Bloss curves have two geometry elements for one horizontal alignment segment. That is the reason for returning a pair.
// Typically the first element of the pair will have the geometry and the second element will be nullptr
IFC_PARSE_API std::pair<Ifc4x3_add2::IfcCurveSegment, Ifc4x3_add2::IfcCurveSegment> mapAlignmentSegment(hierarchy_helper<Ifc4x3_add2>& model, const Ifc4x3_add2::IfcAlignmentSegment& segment);
IFC_PARSE_API std::pair<Ifc4x3_add2::IfcCurveSegment, Ifc4x3_add2::IfcCurveSegment> mapAlignmentHorizontalSegment(hierarchy_helper<Ifc4x3_add2>& model, const Ifc4x3_add2::IfcAlignmentHorizontalSegment& segment);
IFC_PARSE_API std::pair<Ifc4x3_add2::IfcCurveSegment, Ifc4x3_add2::IfcCurveSegment> mapAlignmentVerticalSegment(hierarchy_helper<Ifc4x3_add2>& model, const Ifc4x3_add2::IfcAlignmentVerticalSegment& segment);
IFC_PARSE_API std::pair<Ifc4x3_add2::IfcCurveSegment, Ifc4x3_add2::IfcCurveSegment> mapAlignmentCantSegment(hierarchy_helper<Ifc4x3_add2>& model, const Ifc4x3_add2::IfcAlignmentCantSegment& segment);
#endif
IFC_SCHEMA_API std::pair<Ifc4x3_add2::IfcCurveSegment, Ifc4x3_add2::IfcCurveSegment> mapAlignmentSegment(hierarchy_helper<Ifc4x3_add2>& model, const Ifc4x3_add2::IfcAlignmentSegment& segment);
IFC_SCHEMA_API std::pair<Ifc4x3_add2::IfcCurveSegment, Ifc4x3_add2::IfcCurveSegment> mapAlignmentHorizontalSegment(hierarchy_helper<Ifc4x3_add2>& model, const Ifc4x3_add2::IfcAlignmentHorizontalSegment& segment);
IFC_SCHEMA_API std::pair<Ifc4x3_add2::IfcCurveSegment, Ifc4x3_add2::IfcCurveSegment> mapAlignmentVerticalSegment(hierarchy_helper<Ifc4x3_add2>& model, const Ifc4x3_add2::IfcAlignmentVerticalSegment& segment);
IFC_SCHEMA_API std::pair<Ifc4x3_add2::IfcCurveSegment, Ifc4x3_add2::IfcCurveSegment> mapAlignmentCantSegment(hierarchy_helper<Ifc4x3_add2>& model, const Ifc4x3_add2::IfcAlignmentCantSegment& segment);
#endif
+72 -407
View File
@@ -32,334 +32,62 @@
#include "logger.h"
#include <map>
#ifdef HAS_SCHEMA_2x3
#include "schemas/Ifc2x3.h"
#endif
#ifdef HAS_SCHEMA_4
#include "schemas/Ifc4.h"
#endif
#ifdef HAS_SCHEMA_4x1
#include "schemas/Ifc4x1.h"
#endif
#ifdef HAS_SCHEMA_4x2
#include "schemas/Ifc4x2.h"
#endif
#ifdef HAS_SCHEMA_4x3_rc1
#include "schemas/Ifc4x3_rc1.h"
#endif
#ifdef HAS_SCHEMA_4x3_rc2
#include "schemas/Ifc4x3_rc2.h"
#endif
#ifdef HAS_SCHEMA_4x3_rc3
#include "schemas/Ifc4x3_rc3.h"
#endif
#ifdef HAS_SCHEMA_4x3_rc4
#include "schemas/Ifc4x3_rc4.h"
#endif
#ifdef HAS_SCHEMA_4x3
#include "schemas/Ifc4x3.h"
#endif
#ifdef HAS_SCHEMA_4x3_tc1
#include "schemas/Ifc4x3_tc1.h"
#endif
#ifdef HAS_SCHEMA_4x3_add1
#include "schemas/Ifc4x3_add1.h"
#endif
#ifdef HAS_SCHEMA_4x3_add2
#include "schemas/Ifc4x3_add2.h"
#endif
#include <type_traits>
#include <vector>
#include "file.h"
#include "global_id.h"
namespace {
#ifdef HAS_SCHEMA_2x3
Ifc2x3::IfcObjectDefinition get_parent_of_relation(const Ifc2x3::IfcRelContainedInSpatialStructure& relation) {
return relation.RelatingStructure();
namespace ifcopenshell::hierarchy_detail {
inline const char* parent_attribute_name(const ifcopenshell::declaration& declaration) {
return declaration.name() == "IfcRelContainedInSpatialStructure" ? "RelatingStructure" : "RelatingObject";
}
std::vector<express::Base> get_children_of_relation(const Ifc2x3::IfcRelContainedInSpatialStructure& relation) {
return cast_vector<express::Base>(relation.RelatedElements());
inline const char* children_attribute_name(const ifcopenshell::declaration& declaration) {
return declaration.name() == "IfcRelContainedInSpatialStructure" ? "RelatedElements" : "RelatedObjects";
}
std::vector<express::Base> get_children_of_relation(const Ifc2x3::IfcRelAggregates& relation) {
return cast_vector<express::Base>(relation.RelatedObjects());
template <typename Relation>
express::Base get_parent_of_relation(const Relation& relation) {
return relation.template as<express::Entity>().get(parent_attribute_name(relation.declaration()));
}
void set_children_of_relation(Ifc2x3::IfcRelContainedInSpatialStructure& relation, std::vector<express::Base>& children) {
relation.setRelatedElements(cast_vector<Ifc2x3::IfcProduct>(children));
template <typename Relation>
std::vector<express::Base> get_children_of_relation(const Relation& relation) {
return relation.template as<express::Entity>().get(children_attribute_name(relation.declaration()));
}
void set_children_of_relation(Ifc2x3::IfcRelAggregates& relation, std::vector<express::Base>& children) {
relation.setRelatedObjects(cast_vector<Ifc2x3::IfcObjectDefinition>(children));
}
#endif
#ifdef HAS_SCHEMA_4
Ifc4::IfcObjectDefinition get_parent_of_relation(const Ifc4::IfcRelContainedInSpatialStructure& relation) {
return relation.RelatingStructure();
template <typename Relation>
void set_children_of_relation(Relation& relation, std::vector<express::Base>& children) {
relation.set_attribute_value(children_attribute_name(relation.declaration()), children);
}
std::vector<express::Base> get_children_of_relation(const Ifc4::IfcRelContainedInSpatialStructure& relation) {
return cast_vector<express::Base>(relation.RelatedElements());
}
template <typename Schema, typename = void>
struct styled_item_accepts_presentation_style : std::false_type {};
std::vector<express::Base> get_children_of_relation(const Ifc4::IfcRelAggregates& relation) {
return cast_vector<express::Base>(relation.RelatedObjects());
}
void set_children_of_relation(Ifc4::IfcRelContainedInSpatialStructure& relation, std::vector<express::Base>& children) {
relation.setRelatedElements(cast_vector<Ifc4::IfcProduct>(children));
}
void set_children_of_relation(Ifc4::IfcRelAggregates& relation, std::vector<express::Base>& children) {
relation.setRelatedObjects(cast_vector<Ifc4::IfcObjectDefinition>(children));
}
#endif
#ifdef HAS_SCHEMA_4x1
Ifc4x1::IfcObjectDefinition get_parent_of_relation(const Ifc4x1::IfcRelContainedInSpatialStructure& relation) {
return relation.RelatingStructure();
}
std::vector<express::Base> get_children_of_relation(const Ifc4x1::IfcRelContainedInSpatialStructure& relation) {
return cast_vector<express::Base>(relation.RelatedElements());
}
std::vector<express::Base> get_children_of_relation(const Ifc4x1::IfcRelAggregates& relation) {
return cast_vector<express::Base>(relation.RelatedObjects());
}
void set_children_of_relation(Ifc4x1::IfcRelContainedInSpatialStructure& relation, std::vector<express::Base>& children) {
relation.setRelatedElements(cast_vector<Ifc4x1::IfcProduct>(children));
}
void set_children_of_relation(Ifc4x1::IfcRelAggregates& relation, std::vector<express::Base>& children) {
relation.setRelatedObjects(cast_vector<Ifc4x1::IfcObjectDefinition>(children));
}
#endif
#ifdef HAS_SCHEMA_4x2
Ifc4x2::IfcObjectDefinition get_parent_of_relation(const Ifc4x2::IfcRelContainedInSpatialStructure& relation) {
return relation.RelatingStructure();
}
std::vector<express::Base> get_children_of_relation(const Ifc4x2::IfcRelContainedInSpatialStructure& relation) {
return cast_vector<express::Base>(relation.RelatedElements());
}
std::vector<express::Base> get_children_of_relation(const Ifc4x2::IfcRelAggregates& relation) {
return cast_vector<express::Base>(relation.RelatedObjects());
}
void set_children_of_relation(Ifc4x2::IfcRelContainedInSpatialStructure& relation, std::vector<express::Base>& children) {
relation.setRelatedElements(cast_vector<Ifc4x2::IfcProduct>(children));
}
void set_children_of_relation(Ifc4x2::IfcRelAggregates& relation, std::vector<express::Base>& children) {
relation.setRelatedObjects(cast_vector<Ifc4x2::IfcObjectDefinition>(children));
}
#endif
#ifdef HAS_SCHEMA_4x3_rc1
Ifc4x3_rc1::IfcObjectDefinition get_parent_of_relation(const Ifc4x3_rc1::IfcRelContainedInSpatialStructure& relation) {
return relation.RelatingStructure();
}
std::vector<express::Base> get_children_of_relation(const Ifc4x3_rc1::IfcRelContainedInSpatialStructure& relation) {
return cast_vector<express::Base>(relation.RelatedElements());
}
std::vector<express::Base> get_children_of_relation(const Ifc4x3_rc1::IfcRelAggregates& relation) {
return cast_vector<express::Base>(relation.RelatedObjects());
}
void set_children_of_relation(Ifc4x3_rc1::IfcRelContainedInSpatialStructure& relation, std::vector<express::Base>& children) {
relation.setRelatedElements(cast_vector<Ifc4x3_rc1::IfcProduct>(children));
}
void set_children_of_relation(Ifc4x3_rc1::IfcRelAggregates& relation, std::vector<express::Base>& children) {
relation.setRelatedObjects(cast_vector<Ifc4x3_rc1::IfcObjectDefinition>(children));
}
#endif
#ifdef HAS_SCHEMA_4x3_rc2
Ifc4x3_rc2::IfcObjectDefinition get_parent_of_relation(const Ifc4x3_rc2::IfcRelContainedInSpatialStructure& relation) {
return relation.RelatingStructure();
}
std::vector<express::Base> get_children_of_relation(const Ifc4x3_rc2::IfcRelContainedInSpatialStructure& relation) {
return cast_vector<express::Base>(relation.RelatedElements());
}
std::vector<express::Base> get_children_of_relation(const Ifc4x3_rc2::IfcRelAggregates& relation) {
return cast_vector<express::Base>(relation.RelatedObjects());
}
void set_children_of_relation(Ifc4x3_rc2::IfcRelContainedInSpatialStructure& relation, std::vector<express::Base>& children) {
relation.setRelatedElements(cast_vector<Ifc4x3_rc2::IfcProduct>(children));
}
void set_children_of_relation(Ifc4x3_rc2::IfcRelAggregates& relation, std::vector<express::Base>& children) {
relation.setRelatedObjects(cast_vector<Ifc4x3_rc2::IfcObjectDefinition>(children));
}
#endif
#ifdef HAS_SCHEMA_4x3_rc3
Ifc4x3_rc3::IfcObjectDefinition get_parent_of_relation(const Ifc4x3_rc3::IfcRelContainedInSpatialStructure& relation) {
return relation.RelatingStructure();
}
std::vector<express::Base> get_children_of_relation(const Ifc4x3_rc3::IfcRelContainedInSpatialStructure& relation) {
return cast_vector<express::Base>(relation.RelatedElements());
}
std::vector<express::Base> get_children_of_relation(const Ifc4x3_rc3::IfcRelAggregates& relation) {
return cast_vector<express::Base>(relation.RelatedObjects());
}
void set_children_of_relation(Ifc4x3_rc3::IfcRelContainedInSpatialStructure& relation, std::vector<express::Base>& children) {
relation.setRelatedElements(cast_vector<Ifc4x3_rc3::IfcProduct>(children));
}
void set_children_of_relation(Ifc4x3_rc3::IfcRelAggregates& relation, std::vector<express::Base>& children) {
relation.setRelatedObjects(cast_vector<Ifc4x3_rc3::IfcObjectDefinition>(children));
}
#endif
#ifdef HAS_SCHEMA_4x3_rc4
Ifc4x3_rc4::IfcObjectDefinition get_parent_of_relation(const Ifc4x3_rc4::IfcRelContainedInSpatialStructure& relation) {
return relation.RelatingStructure();
}
std::vector<express::Base> get_children_of_relation(const Ifc4x3_rc4::IfcRelContainedInSpatialStructure& relation) {
return cast_vector<express::Base>(relation.RelatedElements());
}
std::vector<express::Base> get_children_of_relation(const Ifc4x3_rc4::IfcRelAggregates& relation) {
return cast_vector<express::Base>(relation.RelatedObjects());
}
void set_children_of_relation(Ifc4x3_rc4::IfcRelContainedInSpatialStructure& relation, std::vector<express::Base>& children) {
relation.setRelatedElements(cast_vector<Ifc4x3_rc4::IfcProduct>(children));
}
void set_children_of_relation(Ifc4x3_rc4::IfcRelAggregates& relation, std::vector<express::Base>& children) {
relation.setRelatedObjects(cast_vector<Ifc4x3_rc4::IfcObjectDefinition>(children));
}
#endif
#ifdef HAS_SCHEMA_4x3
Ifc4x3::IfcObjectDefinition get_parent_of_relation(const Ifc4x3::IfcRelContainedInSpatialStructure& relation) {
return relation.RelatingStructure();
}
std::vector<express::Base> get_children_of_relation(const Ifc4x3::IfcRelContainedInSpatialStructure& relation) {
return cast_vector<express::Base>(relation.RelatedElements());
}
std::vector<express::Base> get_children_of_relation(const Ifc4x3::IfcRelAggregates& relation) {
return cast_vector<express::Base>(relation.RelatedObjects());
}
void set_children_of_relation(Ifc4x3::IfcRelContainedInSpatialStructure& relation, std::vector<express::Base>& children) {
relation.setRelatedElements(cast_vector<Ifc4x3::IfcProduct>(children));
}
void set_children_of_relation(Ifc4x3::IfcRelAggregates& relation, std::vector<express::Base>& children) {
relation.setRelatedObjects(cast_vector<Ifc4x3::IfcObjectDefinition>(children));
}
#endif
#ifdef HAS_SCHEMA_4x3_tc1
Ifc4x3_tc1::IfcObjectDefinition get_parent_of_relation(const Ifc4x3_tc1::IfcRelContainedInSpatialStructure& relation) {
return relation.RelatingStructure();
}
std::vector<express::Base> get_children_of_relation(const Ifc4x3_tc1::IfcRelContainedInSpatialStructure& relation) {
return cast_vector<express::Base>(relation.RelatedElements());
}
std::vector<express::Base> get_children_of_relation(const Ifc4x3_tc1::IfcRelAggregates& relation) {
return cast_vector<express::Base>(relation.RelatedObjects());
}
void set_children_of_relation(Ifc4x3_tc1::IfcRelContainedInSpatialStructure& relation, std::vector<express::Base>& children) {
relation.setRelatedElements(cast_vector<Ifc4x3_tc1::IfcProduct>(children));
}
void set_children_of_relation(Ifc4x3_tc1::IfcRelAggregates& relation, std::vector<express::Base>& children) {
relation.setRelatedObjects(cast_vector<Ifc4x3_tc1::IfcObjectDefinition>(children));
}
#endif
#ifdef HAS_SCHEMA_4x3_add1
Ifc4x3_add1::IfcObjectDefinition get_parent_of_relation(const Ifc4x3_add1::IfcRelContainedInSpatialStructure& relation) {
return relation.RelatingStructure();
}
std::vector<express::Base> get_children_of_relation(const Ifc4x3_add1::IfcRelContainedInSpatialStructure& relation) {
return cast_vector<express::Base>(relation.RelatedElements());
}
std::vector<express::Base> get_children_of_relation(const Ifc4x3_add1::IfcRelAggregates& relation) {
return cast_vector<express::Base>(relation.RelatedObjects());
}
void set_children_of_relation(Ifc4x3_add1::IfcRelContainedInSpatialStructure& relation, std::vector<express::Base>& children) {
relation.setRelatedElements(cast_vector<Ifc4x3_add1::IfcProduct>(children));
}
void set_children_of_relation(Ifc4x3_add1::IfcRelAggregates& relation, std::vector<express::Base>& children) {
relation.setRelatedObjects(cast_vector<Ifc4x3_add1::IfcObjectDefinition>(children));
}
#endif
#ifdef HAS_SCHEMA_4x3_add2
Ifc4x3_add2::IfcObjectDefinition get_parent_of_relation(const Ifc4x3_add2::IfcRelContainedInSpatialStructure& relation) {
return relation.RelatingStructure();
}
std::vector<express::Base> get_children_of_relation(const Ifc4x3_add2::IfcRelContainedInSpatialStructure& relation) {
return cast_vector<express::Base>(relation.RelatedElements());
}
std::vector<express::Base> get_children_of_relation(const Ifc4x3_add2::IfcRelAggregates& relation) {
return cast_vector<express::Base>(relation.RelatedObjects());
}
std::vector<express::Base> get_children_of_relation(const Ifc4x3_add2::IfcRelNests& relation) {
return cast_vector<express::Base>(relation.RelatedObjects());
}
void set_children_of_relation(Ifc4x3_add2::IfcRelContainedInSpatialStructure& relation, std::vector<express::Base>& children) {
relation.setRelatedElements(cast_vector<Ifc4x3_add2::IfcProduct>(children));
}
void set_children_of_relation(Ifc4x3_add2::IfcRelAggregates& relation, std::vector<express::Base>& children) {
relation.setRelatedObjects(cast_vector<Ifc4x3_add2::IfcObjectDefinition>(children));
}
void set_children_of_relation(Ifc4x3_add2::IfcRelNests& relation, std::vector<express::Base>& children) {
relation.setRelatedObjects(cast_vector<Ifc4x3_add2::IfcObjectDefinition>(children));
}
#endif
express::Base get_parent_of_relation(const express::Base& relation) {
return relation.as<express::Entity>().get("RelatingObject");
}
std::vector<express::Base> get_children_of_relation(const express::Base& relation) {
return relation.as<express::Entity>().get("RelatedElements");
}
void set_children_of_relation(express::Base& relation, std::vector<express::Base>& children) {
return relation.set_attribute_value("RelatedElements", children);
}
} // namespace
template <typename Schema>
class IFC_PARSE_API hierarchy_helper : public ifcopenshell::file {
struct styled_item_accepts_presentation_style<Schema,
std::void_t<decltype(std::declval<typename Schema::IfcStyledItem&>().setStyles(
std::declval<std::vector<typename Schema::IfcPresentationStyle>>()))>> : std::true_type {};
template <typename Schema, bool DirectStyle = styled_item_accepts_presentation_style<Schema>::value>
struct surface_style_type_selector {
using type = typename Schema::IfcPresentationStyleAssignment;
};
template <typename Schema>
struct surface_style_type_selector<Schema, true> {
using type = typename Schema::IfcPresentationStyle;
};
template <typename Schema>
using surface_style_type = typename surface_style_type_selector<Schema>::type;
} // namespace ifcopenshell::hierarchy_detail
template <typename Schema>
class IFC_SCHEMA_API hierarchy_helper : public ifcopenshell::file {
public:
hierarchy_helper() : ifcopenshell::file(&Schema::get_schema()) {}
@@ -444,10 +172,10 @@ class IFC_PARSE_API hierarchy_helper : public ifcopenshell::file {
bool found = false;
for (auto& rel : li) {
try {
if (get_parent_of_relation(rel) == relating_object) {
auto products = get_children_of_relation(rel);
if (ifcopenshell::hierarchy_detail::get_parent_of_relation(rel) == relating_object) {
auto products = ifcopenshell::hierarchy_detail::get_children_of_relation(rel);
products.push_back(add_entity(related_object));
set_children_of_relation(rel, products);
ifcopenshell::hierarchy_detail::set_children_of_relation(rel, products);
found = true;
break;
}
@@ -533,101 +261,38 @@ class IFC_PARSE_API hierarchy_helper : public ifcopenshell::file {
std::map<std::string, typename Schema::IfcGeometricRepresentationContext> contexts_;
};
#ifdef HAS_SCHEMA_2x3
IFC_PARSE_API Ifc2x3::IfcPresentationStyleAssignment addStyleAssignment(hierarchy_helper<Ifc2x3>& model, double red, double green, double blue, double alpha = 1.0);
IFC_PARSE_API Ifc2x3::IfcPresentationStyleAssignment setSurfaceColour(hierarchy_helper<Ifc2x3>& model, const Ifc2x3::IfcProductRepresentation& shape, double red, double green, double blue, double alpha = 1.0);
IFC_PARSE_API Ifc2x3::IfcPresentationStyleAssignment setSurfaceColour(hierarchy_helper<Ifc2x3>& model, const Ifc2x3::IfcRepresentation& shape, double red, double green, double blue, double alpha = 1.0);
IFC_PARSE_API void setSurfaceColour(hierarchy_helper<Ifc2x3>& model, const Ifc2x3::IfcProductRepresentation& shape, const Ifc2x3::IfcPresentationStyleAssignment& style_assignment);
IFC_PARSE_API void setSurfaceColour(hierarchy_helper<Ifc2x3>& model, const Ifc2x3::IfcRepresentation& shape, const Ifc2x3::IfcPresentationStyleAssignment& style_assignment);
#endif
template <typename Schema>
IFC_SCHEMA_API ifcopenshell::hierarchy_detail::surface_style_type<Schema>
addStyleAssignment(hierarchy_helper<Schema>& model, double red, double green, double blue, double alpha = 1.0);
#ifdef HAS_SCHEMA_4
IFC_PARSE_API Ifc4::IfcPresentationStyleAssignment addStyleAssignment(hierarchy_helper<Ifc4>& model, double red, double green, double blue, double alpha = 1.0);
IFC_PARSE_API Ifc4::IfcPresentationStyleAssignment setSurfaceColour(hierarchy_helper<Ifc4>& model, const Ifc4::IfcProductRepresentation& shape, double red, double green, double blue, double alpha = 1.0);
IFC_PARSE_API Ifc4::IfcPresentationStyleAssignment setSurfaceColour(hierarchy_helper<Ifc4>& model, const Ifc4::IfcRepresentation& shape, double red, double green, double blue, double alpha = 1.0);
IFC_PARSE_API void setSurfaceColour(hierarchy_helper<Ifc4>& model, const Ifc4::IfcProductRepresentation& shape, const Ifc4::IfcPresentationStyleAssignment& style_assignment);
IFC_PARSE_API void setSurfaceColour(hierarchy_helper<Ifc4>& model, const Ifc4::IfcRepresentation& shape, const Ifc4::IfcPresentationStyleAssignment& style_assignment);
#endif
template <typename Schema>
IFC_SCHEMA_API ifcopenshell::hierarchy_detail::surface_style_type<Schema>
setSurfaceColour(hierarchy_helper<Schema>& model,
const typename Schema::IfcProductRepresentation& shape,
double red,
double green,
double blue,
double alpha = 1.0);
#ifdef HAS_SCHEMA_4x1
IFC_PARSE_API Ifc4x1::IfcPresentationStyleAssignment addStyleAssignment(hierarchy_helper<Ifc4x1>& model, double red, double green, double blue, double alpha = 1.0);
IFC_PARSE_API Ifc4x1::IfcPresentationStyleAssignment setSurfaceColour(hierarchy_helper<Ifc4x1>& model, const Ifc4x1::IfcProductRepresentation& shape, double red, double green, double blue, double alpha = 1.0);
IFC_PARSE_API Ifc4x1::IfcPresentationStyleAssignment setSurfaceColour(hierarchy_helper<Ifc4x1>& model, const Ifc4x1::IfcRepresentation& shape, double red, double green, double blue, double alpha = 1.0);
IFC_PARSE_API void setSurfaceColour(hierarchy_helper<Ifc4x1>& model, const Ifc4x1::IfcProductRepresentation& shape, const Ifc4x1::IfcPresentationStyleAssignment& style_assignment);
IFC_PARSE_API void setSurfaceColour(hierarchy_helper<Ifc4x1>& model, const Ifc4x1::IfcRepresentation& shape, const Ifc4x1::IfcPresentationStyleAssignment& style_assignment);
#endif
template <typename Schema>
IFC_SCHEMA_API ifcopenshell::hierarchy_detail::surface_style_type<Schema>
setSurfaceColour(hierarchy_helper<Schema>& model,
const typename Schema::IfcRepresentation& shape,
double red,
double green,
double blue,
double alpha = 1.0);
#ifdef HAS_SCHEMA_4x2
IFC_PARSE_API Ifc4x2::IfcPresentationStyleAssignment addStyleAssignment(hierarchy_helper<Ifc4x2>& model, double red, double green, double blue, double alpha = 1.0);
IFC_PARSE_API Ifc4x2::IfcPresentationStyleAssignment setSurfaceColour(hierarchy_helper<Ifc4x2>& model, const Ifc4x2::IfcProductRepresentation& shape, double red, double green, double blue, double alpha = 1.0);
IFC_PARSE_API Ifc4x2::IfcPresentationStyleAssignment setSurfaceColour(hierarchy_helper<Ifc4x2>& model, const Ifc4x2::IfcRepresentation& shape, double red, double green, double blue, double alpha = 1.0);
IFC_PARSE_API void setSurfaceColour(hierarchy_helper<Ifc4x2>& model, const Ifc4x2::IfcProductRepresentation& shape, const Ifc4x2::IfcPresentationStyleAssignment& style_assignment);
IFC_PARSE_API void setSurfaceColour(hierarchy_helper<Ifc4x2>& model, const Ifc4x2::IfcRepresentation& shape, const Ifc4x2::IfcPresentationStyleAssignment& style_assignment);
#endif
template <typename Schema>
IFC_SCHEMA_API void setSurfaceColour(
hierarchy_helper<Schema>& model,
const typename Schema::IfcProductRepresentation& shape,
const ifcopenshell::hierarchy_detail::surface_style_type<Schema>& style);
#ifdef HAS_SCHEMA_4x3_rc1
IFC_PARSE_API Ifc4x3_rc1::IfcPresentationStyleAssignment addStyleAssignment(hierarchy_helper<Ifc4x3_rc1>& model, double red, double green, double blue, double alpha = 1.0);
IFC_PARSE_API Ifc4x3_rc1::IfcPresentationStyleAssignment setSurfaceColour(hierarchy_helper<Ifc4x3_rc1>& model, const Ifc4x3_rc1::IfcProductRepresentation& shape, double red, double green, double blue, double alpha = 1.0);
IFC_PARSE_API Ifc4x3_rc1::IfcPresentationStyleAssignment setSurfaceColour(hierarchy_helper<Ifc4x3_rc1>& model, const Ifc4x3_rc1::IfcRepresentation& shape, double red, double green, double blue, double alpha = 1.0);
IFC_PARSE_API void setSurfaceColour(hierarchy_helper<Ifc4x3_rc1>& model, const Ifc4x3_rc1::IfcProductRepresentation& shape, const Ifc4x3_rc1::IfcPresentationStyleAssignment& style_assignment);
IFC_PARSE_API void setSurfaceColour(hierarchy_helper<Ifc4x3_rc1>& model, const Ifc4x3_rc1::IfcRepresentation& shape, const Ifc4x3_rc1::IfcPresentationStyleAssignment& style_assignment);
#endif
#ifdef HAS_SCHEMA_4x3_rc2
IFC_PARSE_API Ifc4x3_rc2::IfcPresentationStyleAssignment addStyleAssignment(hierarchy_helper<Ifc4x3_rc2>& model, double red, double green, double blue, double alpha = 1.0);
IFC_PARSE_API Ifc4x3_rc2::IfcPresentationStyleAssignment setSurfaceColour(hierarchy_helper<Ifc4x3_rc2>& model, const Ifc4x3_rc2::IfcProductRepresentation& shape, double red, double green, double blue, double alpha = 1.0);
IFC_PARSE_API Ifc4x3_rc2::IfcPresentationStyleAssignment setSurfaceColour(hierarchy_helper<Ifc4x3_rc2>& model, const Ifc4x3_rc2::IfcRepresentation& shape, double red, double green, double blue, double alpha = 1.0);
IFC_PARSE_API void setSurfaceColour(hierarchy_helper<Ifc4x3_rc2>& model, const Ifc4x3_rc2::IfcProductRepresentation& shape, const Ifc4x3_rc2::IfcPresentationStyleAssignment& style_assignment);
IFC_PARSE_API void setSurfaceColour(hierarchy_helper<Ifc4x3_rc2>& model, const Ifc4x3_rc2::IfcRepresentation& shape, const Ifc4x3_rc2::IfcPresentationStyleAssignment& style_assignment);
#endif
#ifdef HAS_SCHEMA_4x3_rc3
IFC_PARSE_API Ifc4x3_rc3::IfcPresentationStyle addStyleAssignment(hierarchy_helper<Ifc4x3_rc3>& model, double red, double green, double blue, double alpha = 1.0);
IFC_PARSE_API Ifc4x3_rc3::IfcPresentationStyle setSurfaceColour(hierarchy_helper<Ifc4x3_rc3>& model, const Ifc4x3_rc3::IfcProductRepresentation& shape, double red, double green, double blue, double alpha = 1.0);
IFC_PARSE_API Ifc4x3_rc3::IfcPresentationStyle setSurfaceColour(hierarchy_helper<Ifc4x3_rc3>& model, const Ifc4x3_rc3::IfcRepresentation& shape, double red, double green, double blue, double alpha = 1.0);
IFC_PARSE_API void setSurfaceColour(hierarchy_helper<Ifc4x3_rc3>& model, const Ifc4x3_rc3::IfcProductRepresentation& shape, const Ifc4x3_rc3::IfcPresentationStyle& style);
IFC_PARSE_API void setSurfaceColour(hierarchy_helper<Ifc4x3_rc3>& model, const Ifc4x3_rc3::IfcRepresentation& shape, const Ifc4x3_rc3::IfcPresentationStyle& style);
#endif
#ifdef HAS_SCHEMA_4x3_rc4
IFC_PARSE_API Ifc4x3_rc4::IfcPresentationStyle addStyleAssignment(hierarchy_helper<Ifc4x3_rc4>& model, double red, double green, double blue, double alpha = 1.0);
IFC_PARSE_API Ifc4x3_rc4::IfcPresentationStyle setSurfaceColour(hierarchy_helper<Ifc4x3_rc4>& model, const Ifc4x3_rc4::IfcProductRepresentation& shape, double red, double green, double blue, double alpha = 1.0);
IFC_PARSE_API Ifc4x3_rc4::IfcPresentationStyle setSurfaceColour(hierarchy_helper<Ifc4x3_rc4>& model, const Ifc4x3_rc4::IfcRepresentation& shape, double red, double green, double blue, double alpha = 1.0);
IFC_PARSE_API void setSurfaceColour(hierarchy_helper<Ifc4x3_rc4>& model, const Ifc4x3_rc4::IfcProductRepresentation& shape, const Ifc4x3_rc4::IfcPresentationStyle& style);
IFC_PARSE_API void setSurfaceColour(hierarchy_helper<Ifc4x3_rc4>& model, const Ifc4x3_rc4::IfcRepresentation& shape, const Ifc4x3_rc4::IfcPresentationStyle& style);
#endif
#ifdef HAS_SCHEMA_4x3
IFC_PARSE_API Ifc4x3::IfcPresentationStyle addStyleAssignment(hierarchy_helper<Ifc4x3>& model, double red, double green, double blue, double alpha = 1.0);
IFC_PARSE_API Ifc4x3::IfcPresentationStyle setSurfaceColour(hierarchy_helper<Ifc4x3>& model, const Ifc4x3::IfcProductRepresentation& shape, double red, double green, double blue, double alpha = 1.0);
IFC_PARSE_API Ifc4x3::IfcPresentationStyle setSurfaceColour(hierarchy_helper<Ifc4x3>& model, const Ifc4x3::IfcRepresentation& shape, double red, double green, double blue, double alpha = 1.0);
IFC_PARSE_API void setSurfaceColour(hierarchy_helper<Ifc4x3>& model, const Ifc4x3::IfcProductRepresentation& shape, const Ifc4x3::IfcPresentationStyle& style);
IFC_PARSE_API void setSurfaceColour(hierarchy_helper<Ifc4x3>& model, const Ifc4x3::IfcRepresentation& shape, const Ifc4x3::IfcPresentationStyle& style);
#endif
#ifdef HAS_SCHEMA_4x3_tc1
IFC_PARSE_API Ifc4x3_tc1::IfcPresentationStyle addStyleAssignment(hierarchy_helper<Ifc4x3_tc1>& model, double red, double green, double blue, double alpha = 1.0);
IFC_PARSE_API Ifc4x3_tc1::IfcPresentationStyle setSurfaceColour(hierarchy_helper<Ifc4x3_tc1>& model, const Ifc4x3_tc1::IfcProductRepresentation& shape, double red, double green, double blue, double alpha = 1.0);
IFC_PARSE_API Ifc4x3_tc1::IfcPresentationStyle setSurfaceColour(hierarchy_helper<Ifc4x3_tc1>& model, const Ifc4x3_tc1::IfcRepresentation& shape, double red, double green, double blue, double alpha = 1.0);
IFC_PARSE_API void setSurfaceColour(hierarchy_helper<Ifc4x3_tc1>& model, const Ifc4x3_tc1::IfcProductRepresentation& shape, const Ifc4x3_tc1::IfcPresentationStyle& style);
IFC_PARSE_API void setSurfaceColour(hierarchy_helper<Ifc4x3_tc1>& model, const Ifc4x3_tc1::IfcRepresentation& shape, const Ifc4x3_tc1::IfcPresentationStyle& style);
#endif
#ifdef HAS_SCHEMA_4x3_add1
IFC_PARSE_API Ifc4x3_add1::IfcPresentationStyle addStyleAssignment(hierarchy_helper<Ifc4x3_add1>& model, double red, double green, double blue, double alpha = 1.0);
IFC_PARSE_API Ifc4x3_add1::IfcPresentationStyle setSurfaceColour(hierarchy_helper<Ifc4x3_add1>& model, const Ifc4x3_add1::IfcProductRepresentation& shape, double red, double green, double blue, double alpha = 1.0);
IFC_PARSE_API Ifc4x3_add1::IfcPresentationStyle setSurfaceColour(hierarchy_helper<Ifc4x3_add1>& model, const Ifc4x3_add1::IfcRepresentation& shape, double red, double green, double blue, double alpha = 1.0);
IFC_PARSE_API void setSurfaceColour(hierarchy_helper<Ifc4x3_add1>& model, const Ifc4x3_add1::IfcProductRepresentation& shape, const Ifc4x3_add1::IfcPresentationStyle& style);
IFC_PARSE_API void setSurfaceColour(hierarchy_helper<Ifc4x3_add1>& model, const Ifc4x3_add1::IfcRepresentation& shape, const Ifc4x3_add1::IfcPresentationStyle& style);
#endif
#ifdef HAS_SCHEMA_4x3_add2
IFC_PARSE_API Ifc4x3_add2::IfcPresentationStyle addStyleAssignment(hierarchy_helper<Ifc4x3_add2>& model, double red, double green, double blue, double alpha = 1.0);
IFC_PARSE_API Ifc4x3_add2::IfcPresentationStyle setSurfaceColour(hierarchy_helper<Ifc4x3_add2>& model, const Ifc4x3_add2::IfcProductRepresentation& shape, double red, double green, double blue, double alpha = 1.0);
IFC_PARSE_API Ifc4x3_add2::IfcPresentationStyle setSurfaceColour(hierarchy_helper<Ifc4x3_add2>& model, const Ifc4x3_add2::IfcRepresentation& shape, double red, double green, double blue, double alpha = 1.0);
IFC_PARSE_API void setSurfaceColour(hierarchy_helper<Ifc4x3_add2>& model, const Ifc4x3_add2::IfcProductRepresentation& shape, const Ifc4x3_add2::IfcPresentationStyle& style);
IFC_PARSE_API void setSurfaceColour(hierarchy_helper<Ifc4x3_add2>& model, const Ifc4x3_add2::IfcRepresentation& shape, const Ifc4x3_add2::IfcPresentationStyle& style);
#endif
template <typename Schema>
IFC_SCHEMA_API void setSurfaceColour(
hierarchy_helper<Schema>& model,
const typename Schema::IfcRepresentation& shape,
const ifcopenshell::hierarchy_detail::surface_style_type<Schema>& style);
#endif
@@ -31,6 +31,19 @@
using namespace std::string_literals;
namespace {
template <typename Person>
auto set_person_identification(Person& person, const std::string& value, int)
-> decltype(person.setIdentification(value), void()) {
person.setIdentification(value);
}
template <typename Person>
void set_person_identification(Person& person, const std::string& value, ...) {
person.setId(value);
}
} // namespace
template <typename Schema>
typename Schema::IfcAxis2Placement3D hierarchy_helper<Schema>::addPlacement3d(
double ox, double oy, double oz, double zx, double zy, double zz, double xx, double xy, double xz) {
@@ -77,14 +90,7 @@ typename Schema::IfcLocalPlacement hierarchy_helper<Schema>::addLocalPlacement(t
template <typename Schema>
typename Schema::IfcOwnerHistory hierarchy_helper<Schema>::addOwnerHistory() {
typename Schema::IfcPerson person = create<typename Schema::IfcPerson>();
#ifdef HAS_SCHEMA_2x3
if constexpr (std::is_same_v<Schema, Ifc2x3>) {
person.setId("");
} else
#endif
{
person.setIdentification("");
}
set_person_identification(person, "", 0);
auto organization = create<typename Schema::IfcOrganization>();
organization.setName("IfcOpenShell");
@@ -486,451 +492,92 @@ typename Schema::IfcSurfaceStyle getSurfaceStyle(hierarchy_helper<Schema>& file,
}
template <typename Schema>
typename Schema::IfcPresentationStyleAssignment addStyleAssignment_2x3(hierarchy_helper<Schema>& file, double r, double g, double b, double a = 1.0) {
ifcopenshell::hierarchy_detail::surface_style_type<Schema>
addStyleAssignment(hierarchy_helper<Schema>& file, double r, double g, double b, double a) {
auto surface_style = getSurfaceStyle<Schema>(file, r, g, b, a);
auto style_assignment = file.template create<typename Schema::IfcPresentationStyleAssignment>();
style_assignment.setStyles(std::vector<typename Schema::IfcPresentationStyleSelect>{surface_style});
return style_assignment;
if constexpr (ifcopenshell::hierarchy_detail::styled_item_accepts_presentation_style<Schema>::value) {
return surface_style;
} else {
auto style_assignment = file.template create<typename Schema::IfcPresentationStyleAssignment>();
style_assignment.setStyles(std::vector<typename Schema::IfcPresentationStyleSelect>{surface_style});
return style_assignment;
}
}
namespace {
template <typename Schema, typename = void>
struct styled_item_accepts_style_assignment_select : std::false_type {};
template <typename Schema>
struct styled_item_accepts_style_assignment_select<Schema,
std::void_t<typename Schema::IfcStyleAssignmentSelect>> : std::true_type {};
template <typename Schema>
typename Schema::IfcStyledItem create_styled_item(
ifcopenshell::file* file,
const typename Schema::IfcRepresentationItem& item,
const ifcopenshell::hierarchy_detail::surface_style_type<Schema>& style) {
auto sitem = file->template create<typename Schema::IfcStyledItem>();
sitem.setItem(item);
if constexpr (ifcopenshell::hierarchy_detail::styled_item_accepts_presentation_style<Schema>::value) {
sitem.setStyles(std::vector<typename Schema::IfcPresentationStyle>{style});
} else if constexpr (styled_item_accepts_style_assignment_select<Schema>::value) {
sitem.setStyles(std::vector<typename Schema::IfcStyleAssignmentSelect>{style});
} else {
sitem.setStyles(std::vector<typename Schema::IfcPresentationStyleAssignment>{style});
}
return sitem;
}
} // namespace
template <typename Schema>
ifcopenshell::hierarchy_detail::surface_style_type<Schema>
setSurfaceColour(hierarchy_helper<Schema>& file,
const typename Schema::IfcProductRepresentation& shape,
double r,
double g,
double b,
double a) {
auto style = addStyleAssignment<Schema>(file, r, g, b, a);
setSurfaceColour(file, shape, style);
return style;
}
template <typename Schema>
typename Schema::IfcPresentationStyle addStyleAssignment_4x3(hierarchy_helper<Schema>& file, double r, double g, double b, double a = 1.0) {
return getSurfaceStyle<Schema>(file, r, g, b, a);
ifcopenshell::hierarchy_detail::surface_style_type<Schema>
setSurfaceColour(hierarchy_helper<Schema>& file,
const typename Schema::IfcRepresentation& shape,
double r,
double g,
double b,
double a) {
auto style = addStyleAssignment<Schema>(file, r, g, b, a);
setSurfaceColour(file, shape, style);
return style;
}
template <typename Schema>
typename Schema::IfcPresentationStyleAssignment setSurfaceColour_2x3(hierarchy_helper<Schema>& file, typename Schema::IfcProductRepresentation shape, double r, double g, double b, double a) {
typename Schema::IfcPresentationStyleAssignment style_assignment = addStyleAssignment_2x3(file, r, g, b, a);
setSurfaceColour_2x3(file, shape, style_assignment);
return style_assignment;
}
template <typename Schema>
typename Schema::IfcPresentationStyle setSurfaceColour_4x3(hierarchy_helper<Schema>& file, typename Schema::IfcProductRepresentation shape, double r, double g, double b, double a) {
typename Schema::IfcPresentationStyle style_assignment = addStyleAssignment_4x3(file, r, g, b, a);
setSurfaceColour_4x3(file, shape, style_assignment);
return style_assignment;
}
template <typename Schema>
typename Schema::IfcPresentationStyleAssignment setSurfaceColour_2x3(hierarchy_helper<Schema>& file, typename Schema::IfcRepresentation shape, double r, double g, double b, double a) {
typename Schema::IfcPresentationStyleAssignment style_assignment = addStyleAssignment_2x3(file, r, g, b, a);
setSurfaceColour_2x3(file, shape, style_assignment);
return style_assignment;
}
template <typename Schema>
typename Schema::IfcPresentationStyle setSurfaceColour_4x3(hierarchy_helper<Schema>& file, typename Schema::IfcRepresentation shape, double r, double g, double b, double a) {
typename Schema::IfcPresentationStyle style_assignment = addStyleAssignment_4x3(file, r, g, b, a);
setSurfaceColour_4x3(file, shape, style_assignment);
return style_assignment;
}
template <typename Schema>
void setSurfaceColour_2x3(hierarchy_helper<Schema>& file, typename Schema::IfcProductRepresentation shape, typename Schema::IfcPresentationStyleAssignment style_assignment) {
void setSurfaceColour(
hierarchy_helper<Schema>& file,
const typename Schema::IfcProductRepresentation& shape,
const ifcopenshell::hierarchy_detail::surface_style_type<Schema>& style) {
auto reps = shape.Representations();
for (auto& rep : reps) {
setSurfaceColour_2x3(file, rep, style_assignment);
setSurfaceColour(file, rep, style);
}
}
template <typename Schema>
void setSurfaceColour_4x3(hierarchy_helper<Schema>& file, typename Schema::IfcProductRepresentation shape, typename Schema::IfcPresentationStyle style) {
auto reps = shape.Representations();
for (auto& rep : reps) {
setSurfaceColour_4x3(file, rep, style);
}
}
#ifdef HAS_SCHEMA_2x3
Ifc2x3::IfcStyledItem create_styled_item(ifcopenshell::file* file, const Ifc2x3::IfcRepresentationItem& item, const Ifc2x3::IfcPresentationStyleAssignment& style_assignment) {
auto sitem = file->create<Ifc2x3::IfcStyledItem>();
sitem.setItem(item);
sitem.setStyles(std::vector<Ifc2x3::IfcPresentationStyleAssignment>{style_assignment});
return sitem;
}
#endif
#ifdef HAS_SCHEMA_4
Ifc4::IfcStyledItem create_styled_item(ifcopenshell::file* file, Ifc4::IfcRepresentationItem item, Ifc4::IfcPresentationStyleAssignment style_assignment) {
auto sitem = file->create<Ifc4::IfcStyledItem>();
sitem.setItem(item);
sitem.setStyles(std::vector<Ifc4::IfcStyleAssignmentSelect>{style_assignment});
return sitem;
}
#endif
#ifdef HAS_SCHEMA_4x1
Ifc4x1::IfcStyledItem create_styled_item(ifcopenshell::file* file, const Ifc4x1::IfcRepresentationItem& item, const Ifc4x1::IfcPresentationStyleAssignment& style_assignment) {
auto sitem = file->create<Ifc4x1::IfcStyledItem>();
sitem.setItem(item);
sitem.setStyles(std::vector<Ifc4x1::IfcStyleAssignmentSelect>{style_assignment});
return sitem;
}
#endif
#ifdef HAS_SCHEMA_4x2
Ifc4x2::IfcStyledItem create_styled_item(ifcopenshell::file* file, const Ifc4x2::IfcRepresentationItem& item, const Ifc4x2::IfcPresentationStyleAssignment& style_assignment) {
auto sitem = file->create<Ifc4x2::IfcStyledItem>();
sitem.setItem(item);
sitem.setStyles(std::vector<Ifc4x2::IfcStyleAssignmentSelect>{style_assignment});
return sitem;
}
#endif
#ifdef HAS_SCHEMA_4x3_rc1
Ifc4x3_rc1::IfcStyledItem create_styled_item(ifcopenshell::file* file, const Ifc4x3_rc1::IfcRepresentationItem& item, const Ifc4x3_rc1::IfcPresentationStyleAssignment& style_assignment) {
auto sitem = file->create<Ifc4x3_rc1::IfcStyledItem>();
sitem.setItem(item);
sitem.setStyles(std::vector<Ifc4x3_rc1::IfcStyleAssignmentSelect>{style_assignment});
return sitem;
}
#endif
#ifdef HAS_SCHEMA_4x3_rc2
Ifc4x3_rc2::IfcStyledItem create_styled_item(ifcopenshell::file* file, const Ifc4x3_rc2::IfcRepresentationItem& item, const Ifc4x3_rc2::IfcPresentationStyleAssignment& style_assignment) {
auto sitem = file->create<Ifc4x3_rc2::IfcStyledItem>();
sitem.setItem(item);
sitem.setStyles(std::vector<Ifc4x3_rc2::IfcStyleAssignmentSelect>{style_assignment});
return sitem;
}
#endif
#ifdef HAS_SCHEMA_4x3_rc3
Ifc4x3_rc3::IfcStyledItem create_styled_item(ifcopenshell::file* file, const Ifc4x3_rc3::IfcRepresentationItem& item, const Ifc4x3_rc3::IfcPresentationStyle& style) {
auto sitem = file->create<Ifc4x3_rc3::IfcStyledItem>();
sitem.setItem(item);
sitem.setStyles(std::vector<Ifc4x3_rc3::IfcPresentationStyle>{style});
return sitem;
}
#endif
#ifdef HAS_SCHEMA_4x3_rc4
Ifc4x3_rc4::IfcStyledItem create_styled_item(ifcopenshell::file* file, const Ifc4x3_rc4::IfcRepresentationItem& item, const Ifc4x3_rc4::IfcPresentationStyle& style) {
auto sitem = file->create<Ifc4x3_rc4::IfcStyledItem>();
sitem.setItem(item);
sitem.setStyles(std::vector<Ifc4x3_rc4::IfcPresentationStyle>{style});
return sitem;
}
#endif
#ifdef HAS_SCHEMA_4x3
Ifc4x3::IfcStyledItem create_styled_item(ifcopenshell::file* file, const Ifc4x3::IfcRepresentationItem& item, const Ifc4x3::IfcPresentationStyle& style) {
auto sitem = file->create<Ifc4x3::IfcStyledItem>();
sitem.setItem(item);
sitem.setStyles(std::vector<Ifc4x3::IfcPresentationStyle>{style});
return sitem;
}
#endif
#ifdef HAS_SCHEMA_4x3_tc1
Ifc4x3_tc1::IfcStyledItem create_styled_item(ifcopenshell::file* file, const Ifc4x3_tc1::IfcRepresentationItem& item, const Ifc4x3_tc1::IfcPresentationStyle& style) {
auto sitem = file->create<Ifc4x3_tc1::IfcStyledItem>();
sitem.setItem(item);
sitem.setStyles(std::vector<Ifc4x3_tc1::IfcPresentationStyle>{style});
return sitem;
}
#endif
#ifdef HAS_SCHEMA_4x3_add1
Ifc4x3_add1::IfcStyledItem create_styled_item(ifcopenshell::file* file, const Ifc4x3_add1::IfcRepresentationItem& item, const Ifc4x3_add1::IfcPresentationStyle& style) {
auto sitem = file->create<Ifc4x3_add1::IfcStyledItem>();
sitem.setItem(item);
sitem.setStyles(std::vector<Ifc4x3_add1::IfcPresentationStyle>{style});
return sitem;
}
#endif
#ifdef HAS_SCHEMA_4x3_add2
Ifc4x3_add2::IfcStyledItem create_styled_item(ifcopenshell::file* file, const Ifc4x3_add2::IfcRepresentationItem& item, const Ifc4x3_add2::IfcPresentationStyle& style) {
auto sitem = file->create<Ifc4x3_add2::IfcStyledItem>();
sitem.setItem(item);
sitem.setStyles(std::vector<Ifc4x3_add2::IfcPresentationStyle>{style});
return sitem;
}
#endif
template <typename Schema>
void setSurfaceColour_2x3(hierarchy_helper<Schema>& file, typename Schema::IfcRepresentation rep, typename Schema::IfcPresentationStyleAssignment style_assignment) {
void setSurfaceColour(
hierarchy_helper<Schema>& file,
const typename Schema::IfcRepresentation& rep,
const ifcopenshell::hierarchy_detail::surface_style_type<Schema>& style) {
auto items = rep.Items();
for (auto& item : items) {
create_styled_item(&file, item, style_assignment);
create_styled_item<Schema>(&file, item, style);
}
}
template <typename Schema>
void setSurfaceColour_4x3(hierarchy_helper<Schema>& file, typename Schema::IfcRepresentation rep, typename Schema::IfcPresentationStyle style) {
// @todo is there still a difference here?
auto items = rep.Items();
for (auto& item : items) {
create_styled_item(&file, item, style);
}
}
#ifdef HAS_SCHEMA_2x3
Ifc2x3::IfcPresentationStyleAssignment addStyleAssignment(hierarchy_helper<Ifc2x3>& file, double r, double g, double b, double a) {
return addStyleAssignment_2x3(file, r, g, b, a);
}
Ifc2x3::IfcPresentationStyleAssignment setSurfaceColour(hierarchy_helper<Ifc2x3>& file, const Ifc2x3::IfcProductRepresentation& shape, double r, double g, double b, double a) {
return setSurfaceColour_2x3(file, shape, r, g, b, a);
}
Ifc2x3::IfcPresentationStyleAssignment setSurfaceColour(hierarchy_helper<Ifc2x3>& file, const Ifc2x3::IfcRepresentation& shape, double r, double g, double b, double a) {
return setSurfaceColour_2x3(file, shape, r, g, b, a);
}
void setSurfaceColour(hierarchy_helper<Ifc2x3>& file, const Ifc2x3::IfcProductRepresentation& shape, const Ifc2x3::IfcPresentationStyleAssignment& style_assignment) {
setSurfaceColour_2x3(file, shape, style_assignment);
}
void setSurfaceColour(hierarchy_helper<Ifc2x3>& file, const Ifc2x3::IfcRepresentation& shape, const Ifc2x3::IfcPresentationStyleAssignment& style_assignment) {
setSurfaceColour_2x3(file, shape, style_assignment);
}
#endif
#ifdef HAS_SCHEMA_4
Ifc4::IfcPresentationStyleAssignment addStyleAssignment(hierarchy_helper<Ifc4>& file, double r, double g, double b, double a) {
return addStyleAssignment_2x3(file, r, g, b, a);
}
Ifc4::IfcPresentationStyleAssignment setSurfaceColour(hierarchy_helper<Ifc4>& file, Ifc4::IfcProductRepresentation shape, double r, double g, double b, double a) {
return setSurfaceColour_2x3(file, shape, r, g, b, a);
}
Ifc4::IfcPresentationStyleAssignment setSurfaceColour(hierarchy_helper<Ifc4>& file, Ifc4::IfcRepresentation shape, double r, double g, double b, double a) {
return setSurfaceColour_2x3(file, shape, r, g, b, a);
}
void setSurfaceColour(hierarchy_helper<Ifc4>& file, Ifc4::IfcProductRepresentation shape, Ifc4::IfcPresentationStyleAssignment style_assignment) {
setSurfaceColour_2x3(file, shape, style_assignment);
}
void setSurfaceColour(hierarchy_helper<Ifc4>& file, Ifc4::IfcRepresentation shape, Ifc4::IfcPresentationStyleAssignment style_assignment) {
setSurfaceColour_2x3(file, shape, style_assignment);
}
#endif
#ifdef HAS_SCHEMA_4x1
Ifc4x1::IfcPresentationStyleAssignment addStyleAssignment(hierarchy_helper<Ifc4x1>& file, double r, double g, double b, double a) {
return addStyleAssignment_2x3(file, r, g, b, a);
}
Ifc4x1::IfcPresentationStyleAssignment setSurfaceColour(hierarchy_helper<Ifc4x1>& file, const Ifc4x1::IfcProductRepresentation& shape, double r, double g, double b, double a) {
return setSurfaceColour_2x3(file, shape, r, g, b, a);
}
Ifc4x1::IfcPresentationStyleAssignment setSurfaceColour(hierarchy_helper<Ifc4x1>& file, const Ifc4x1::IfcRepresentation& shape, double r, double g, double b, double a) {
return setSurfaceColour_2x3(file, shape, r, g, b, a);
}
void setSurfaceColour(hierarchy_helper<Ifc4x1>& file, const Ifc4x1::IfcProductRepresentation& shape, const Ifc4x1::IfcPresentationStyleAssignment& style_assignment) {
setSurfaceColour_2x3(file, shape, style_assignment);
}
void setSurfaceColour(hierarchy_helper<Ifc4x1>& file, const Ifc4x1::IfcRepresentation& shape, const Ifc4x1::IfcPresentationStyleAssignment& style_assignment) {
setSurfaceColour_2x3(file, shape, style_assignment);
}
#endif
#ifdef HAS_SCHEMA_4x2
Ifc4x2::IfcPresentationStyleAssignment addStyleAssignment(hierarchy_helper<Ifc4x2>& file, double r, double g, double b, double a) {
return addStyleAssignment_2x3(file, r, g, b, a);
}
Ifc4x2::IfcPresentationStyleAssignment setSurfaceColour(hierarchy_helper<Ifc4x2>& file, const Ifc4x2::IfcProductRepresentation& shape, double r, double g, double b, double a) {
return setSurfaceColour_2x3(file, shape, r, g, b, a);
}
Ifc4x2::IfcPresentationStyleAssignment setSurfaceColour(hierarchy_helper<Ifc4x2>& file, const Ifc4x2::IfcRepresentation& shape, double r, double g, double b, double a) {
return setSurfaceColour_2x3(file, shape, r, g, b, a);
}
void setSurfaceColour(hierarchy_helper<Ifc4x2>& file, const Ifc4x2::IfcProductRepresentation& shape, const Ifc4x2::IfcPresentationStyleAssignment& style_assignment) {
setSurfaceColour_2x3(file, shape, style_assignment);
}
void setSurfaceColour(hierarchy_helper<Ifc4x2>& file, const Ifc4x2::IfcRepresentation& shape, const Ifc4x2::IfcPresentationStyleAssignment& style_assignment) {
setSurfaceColour_2x3(file, shape, style_assignment);
}
#endif
#ifdef HAS_SCHEMA_4x3_rc1
Ifc4x3_rc1::IfcPresentationStyleAssignment addStyleAssignment(hierarchy_helper<Ifc4x3_rc1>& file, double r, double g, double b, double a) {
return addStyleAssignment_2x3(file, r, g, b, a);
}
Ifc4x3_rc1::IfcPresentationStyleAssignment setSurfaceColour(hierarchy_helper<Ifc4x3_rc1>& file, const Ifc4x3_rc1::IfcProductRepresentation& shape, double r, double g, double b, double a) {
return setSurfaceColour_2x3(file, shape, r, g, b, a);
}
Ifc4x3_rc1::IfcPresentationStyleAssignment setSurfaceColour(hierarchy_helper<Ifc4x3_rc1>& file, const Ifc4x3_rc1::IfcRepresentation& shape, double r, double g, double b, double a) {
return setSurfaceColour_2x3(file, shape, r, g, b, a);
}
void setSurfaceColour(hierarchy_helper<Ifc4x3_rc1>& file, const Ifc4x3_rc1::IfcProductRepresentation& shape, const Ifc4x3_rc1::IfcPresentationStyleAssignment& style_assignment) {
setSurfaceColour_2x3(file, shape, style_assignment);
}
void setSurfaceColour(hierarchy_helper<Ifc4x3_rc1>& file, const Ifc4x3_rc1::IfcRepresentation& shape, const Ifc4x3_rc1::IfcPresentationStyleAssignment& style_assignment) {
setSurfaceColour_2x3(file, shape, style_assignment);
}
#endif
#ifdef HAS_SCHEMA_4x3_rc2
Ifc4x3_rc2::IfcPresentationStyleAssignment addStyleAssignment(hierarchy_helper<Ifc4x3_rc2>& file, double r, double g, double b, double a) {
return addStyleAssignment_2x3(file, r, g, b, a);
}
Ifc4x3_rc2::IfcPresentationStyleAssignment setSurfaceColour(hierarchy_helper<Ifc4x3_rc2>& file, const Ifc4x3_rc2::IfcProductRepresentation& shape, double r, double g, double b, double a) {
return setSurfaceColour_2x3(file, shape, r, g, b, a);
}
Ifc4x3_rc2::IfcPresentationStyleAssignment setSurfaceColour(hierarchy_helper<Ifc4x3_rc2>& file, const Ifc4x3_rc2::IfcRepresentation& shape, double r, double g, double b, double a) {
return setSurfaceColour_2x3(file, shape, r, g, b, a);
}
void setSurfaceColour(hierarchy_helper<Ifc4x3_rc2>& file, const Ifc4x3_rc2::IfcProductRepresentation& shape, const Ifc4x3_rc2::IfcPresentationStyleAssignment& style_assignment) {
setSurfaceColour_2x3(file, shape, style_assignment);
}
void setSurfaceColour(hierarchy_helper<Ifc4x3_rc2>& file, const Ifc4x3_rc2::IfcRepresentation& shape, const Ifc4x3_rc2::IfcPresentationStyleAssignment& style_assignment) {
setSurfaceColour_2x3(file, shape, style_assignment);
}
#endif
#ifdef HAS_SCHEMA_4x3_rc3
Ifc4x3_rc3::IfcPresentationStyle addStyleAssignment(hierarchy_helper<Ifc4x3_rc3>& file, double r, double g, double b, double a) {
return addStyleAssignment_4x3(file, r, g, b, a);
}
Ifc4x3_rc3::IfcPresentationStyle setSurfaceColour(hierarchy_helper<Ifc4x3_rc3>& file, const Ifc4x3_rc3::IfcProductRepresentation& shape, double r, double g, double b, double a) {
return setSurfaceColour_4x3(file, shape, r, g, b, a);
}
Ifc4x3_rc3::IfcPresentationStyle setSurfaceColour(hierarchy_helper<Ifc4x3_rc3>& file, const Ifc4x3_rc3::IfcRepresentation& shape, double r, double g, double b, double a) {
return setSurfaceColour_4x3(file, shape, r, g, b, a);
}
void setSurfaceColour(hierarchy_helper<Ifc4x3_rc3>& file, const Ifc4x3_rc3::IfcProductRepresentation& shape, const Ifc4x3_rc3::IfcPresentationStyle& style) {
setSurfaceColour_4x3(file, shape, style);
}
void setSurfaceColour(hierarchy_helper<Ifc4x3_rc3>& file, const Ifc4x3_rc3::IfcRepresentation& shape, const Ifc4x3_rc3::IfcPresentationStyle& style) {
setSurfaceColour_4x3(file, shape, style);
}
#endif
#ifdef HAS_SCHEMA_4x3_rc4
Ifc4x3_rc4::IfcPresentationStyle addStyleAssignment(hierarchy_helper<Ifc4x3_rc4>& file, double r, double g, double b, double a) {
return addStyleAssignment_4x3(file, r, g, b, a);
}
Ifc4x3_rc4::IfcPresentationStyle setSurfaceColour(hierarchy_helper<Ifc4x3_rc4>& file, const Ifc4x3_rc4::IfcProductRepresentation& shape, double r, double g, double b, double a) {
return setSurfaceColour_4x3(file, shape, r, g, b, a);
}
Ifc4x3_rc4::IfcPresentationStyle setSurfaceColour(hierarchy_helper<Ifc4x3_rc4>& file, const Ifc4x3_rc4::IfcRepresentation& shape, double r, double g, double b, double a) {
return setSurfaceColour_4x3(file, shape, r, g, b, a);
}
void setSurfaceColour(hierarchy_helper<Ifc4x3_rc4>& file, const Ifc4x3_rc4::IfcProductRepresentation& shape, const Ifc4x3_rc4::IfcPresentationStyle& style) {
setSurfaceColour_4x3(file, shape, style);
}
void setSurfaceColour(hierarchy_helper<Ifc4x3_rc4>& file, const Ifc4x3_rc4::IfcRepresentation& shape, const Ifc4x3_rc4::IfcPresentationStyle& style) {
setSurfaceColour_4x3(file, shape, style);
}
#endif
#ifdef HAS_SCHEMA_4x3
Ifc4x3::IfcPresentationStyle addStyleAssignment(hierarchy_helper<Ifc4x3>& file, double r, double g, double b, double a) {
return addStyleAssignment_4x3(file, r, g, b, a);
}
Ifc4x3::IfcPresentationStyle setSurfaceColour(hierarchy_helper<Ifc4x3>& file, const Ifc4x3::IfcProductRepresentation& shape, double r, double g, double b, double a) {
return setSurfaceColour_4x3(file, shape, r, g, b, a);
}
Ifc4x3::IfcPresentationStyle setSurfaceColour(hierarchy_helper<Ifc4x3>& file, const Ifc4x3::IfcRepresentation& shape, double r, double g, double b, double a) {
return setSurfaceColour_4x3(file, shape, r, g, b, a);
}
void setSurfaceColour(hierarchy_helper<Ifc4x3>& file, const Ifc4x3::IfcProductRepresentation& shape, const Ifc4x3::IfcPresentationStyle& style) {
setSurfaceColour_4x3(file, shape, style);
}
void setSurfaceColour(hierarchy_helper<Ifc4x3>& file, const Ifc4x3::IfcRepresentation& shape, const Ifc4x3::IfcPresentationStyle& style) {
setSurfaceColour_4x3(file, shape, style);
}
#endif
#ifdef HAS_SCHEMA_4x3_tc1
Ifc4x3_tc1::IfcPresentationStyle addStyleAssignment(hierarchy_helper<Ifc4x3_tc1>& file, double r, double g, double b, double a) {
return addStyleAssignment_4x3(file, r, g, b, a);
}
Ifc4x3_tc1::IfcPresentationStyle setSurfaceColour(hierarchy_helper<Ifc4x3_tc1>& file, const Ifc4x3_tc1::IfcProductRepresentation& shape, double r, double g, double b, double a) {
return setSurfaceColour_4x3(file, shape, r, g, b, a);
}
Ifc4x3_tc1::IfcPresentationStyle setSurfaceColour(hierarchy_helper<Ifc4x3_tc1>& file, const Ifc4x3_tc1::IfcRepresentation& shape, double r, double g, double b, double a) {
return setSurfaceColour_4x3(file, shape, r, g, b, a);
}
void setSurfaceColour(hierarchy_helper<Ifc4x3_tc1>& file, const Ifc4x3_tc1::IfcProductRepresentation& shape, const Ifc4x3_tc1::IfcPresentationStyle& style) {
setSurfaceColour_4x3(file, shape, style);
}
void setSurfaceColour(hierarchy_helper<Ifc4x3_tc1>& file, const Ifc4x3_tc1::IfcRepresentation& shape, const Ifc4x3_tc1::IfcPresentationStyle& style) {
setSurfaceColour_4x3(file, shape, style);
}
#endif
#ifdef HAS_SCHEMA_4x3_add1
Ifc4x3_add1::IfcPresentationStyle addStyleAssignment(hierarchy_helper<Ifc4x3_add1>& file, double r, double g, double b, double a) {
return addStyleAssignment_4x3(file, r, g, b, a);
}
Ifc4x3_add1::IfcPresentationStyle setSurfaceColour(hierarchy_helper<Ifc4x3_add1>& file, const Ifc4x3_add1::IfcProductRepresentation& shape, double r, double g, double b, double a) {
return setSurfaceColour_4x3(file, shape, r, g, b, a);
}
Ifc4x3_add1::IfcPresentationStyle setSurfaceColour(hierarchy_helper<Ifc4x3_add1>& file, const Ifc4x3_add1::IfcRepresentation& shape, double r, double g, double b, double a) {
return setSurfaceColour_4x3(file, shape, r, g, b, a);
}
void setSurfaceColour(hierarchy_helper<Ifc4x3_add1>& file, const Ifc4x3_add1::IfcProductRepresentation& shape, const Ifc4x3_add1::IfcPresentationStyle& style) {
setSurfaceColour_4x3(file, shape, style);
}
void setSurfaceColour(hierarchy_helper<Ifc4x3_add1>& file, const Ifc4x3_add1::IfcRepresentation& shape, const Ifc4x3_add1::IfcPresentationStyle& style) {
setSurfaceColour_4x3(file, shape, style);
}
#endif
#ifdef HAS_SCHEMA_4x3_add2
Ifc4x3_add2::IfcPresentationStyle addStyleAssignment(hierarchy_helper<Ifc4x3_add2>& file, double r, double g, double b, double a) {
return addStyleAssignment_4x3(file, r, g, b, a);
}
Ifc4x3_add2::IfcPresentationStyle setSurfaceColour(hierarchy_helper<Ifc4x3_add2>& file, const Ifc4x3_add2::IfcProductRepresentation& shape, double r, double g, double b, double a) {
return setSurfaceColour_4x3(file, shape, r, g, b, a);
}
Ifc4x3_add2::IfcPresentationStyle setSurfaceColour(hierarchy_helper<Ifc4x3_add2>& file, const Ifc4x3_add2::IfcRepresentation& shape, double r, double g, double b, double a) {
return setSurfaceColour_4x3(file, shape, r, g, b, a);
}
void setSurfaceColour(hierarchy_helper<Ifc4x3_add2>& file, const Ifc4x3_add2::IfcProductRepresentation& shape, const Ifc4x3_add2::IfcPresentationStyle& style) {
setSurfaceColour_4x3(file, shape, style);
}
void setSurfaceColour(hierarchy_helper<Ifc4x3_add2>& file, const Ifc4x3_add2::IfcRepresentation& shape, const Ifc4x3_add2::IfcPresentationStyle& style) {
setSurfaceColour_4x3(file, shape, style);
}
#endif
template <typename Schema>
typename Schema::IfcProductDefinitionShape hierarchy_helper<Schema>::addMappedItem(
typename Schema::IfcShapeRepresentation rep,
@@ -1071,39 +718,35 @@ typename Schema::IfcGeometricRepresentationSubContext hierarchy_helper<Schema>::
return rep_subcontext;
}
#ifdef HAS_SCHEMA_2x3
template IFC_PARSE_API class hierarchy_helper<Ifc2x3>;
#endif
#ifdef HAS_SCHEMA_4
template IFC_PARSE_API class hierarchy_helper<Ifc4>;
#endif
#ifdef HAS_SCHEMA_4x1
template IFC_PARSE_API class hierarchy_helper<Ifc4x1>;
#endif
#ifdef HAS_SCHEMA_4x2
template IFC_PARSE_API class hierarchy_helper<Ifc4x2>;
#endif
#ifdef HAS_SCHEMA_4x3_rc1
template IFC_PARSE_API class hierarchy_helper<Ifc4x3_rc1>;
#endif
#ifdef HAS_SCHEMA_4x3_rc2
template IFC_PARSE_API class hierarchy_helper<Ifc4x3_rc2>;
#endif
#ifdef HAS_SCHEMA_4x3_rc3
template IFC_PARSE_API class hierarchy_helper<Ifc4x3_rc3>;
#endif
#ifdef HAS_SCHEMA_4x3_rc4
template IFC_PARSE_API class hierarchy_helper<Ifc4x3_rc4>;
#endif
#ifdef HAS_SCHEMA_4x3
template IFC_PARSE_API class hierarchy_helper<Ifc4x3>;
#endif
#ifdef HAS_SCHEMA_4x3_tc1
template IFC_PARSE_API class hierarchy_helper<Ifc4x3_tc1>;
#endif
#ifdef HAS_SCHEMA_4x3_add1
template IFC_PARSE_API class hierarchy_helper<Ifc4x3_add1>;
#endif
#ifdef HAS_SCHEMA_4x3_add2
template IFC_PARSE_API class hierarchy_helper<Ifc4x3_add2>;
#endif
template IFC_SCHEMA_API class hierarchy_helper<IfcSchema>;
template IFC_SCHEMA_API ifcopenshell::hierarchy_detail::surface_style_type<IfcSchema>
addStyleAssignment<IfcSchema>(hierarchy_helper<IfcSchema>&, double, double, double, double);
template IFC_SCHEMA_API ifcopenshell::hierarchy_detail::surface_style_type<IfcSchema>
setSurfaceColour<IfcSchema>(
hierarchy_helper<IfcSchema>&,
const IfcSchema::IfcProductRepresentation&,
double,
double,
double,
double);
template IFC_SCHEMA_API ifcopenshell::hierarchy_detail::surface_style_type<IfcSchema>
setSurfaceColour<IfcSchema>(
hierarchy_helper<IfcSchema>&,
const IfcSchema::IfcRepresentation&,
double,
double,
double,
double);
template IFC_SCHEMA_API void setSurfaceColour<IfcSchema>(
hierarchy_helper<IfcSchema>&,
const IfcSchema::IfcProductRepresentation&,
const ifcopenshell::hierarchy_detail::surface_style_type<IfcSchema>&);
template IFC_SCHEMA_API void setSurfaceColour<IfcSchema>(
hierarchy_helper<IfcSchema>&,
const IfcSchema::IfcRepresentation&,
const ifcopenshell::hierarchy_detail::surface_style_type<IfcSchema>&);
+7
View File
@@ -22,14 +22,21 @@
#ifdef SWIG
#define IFC_PARSE_API
#define IFC_SCHEMA_API
#elif defined(_WIN32)
#ifdef IFC_PARSE_EXPORTS
#define IFC_PARSE_API __declspec(dllexport)
#else
#define IFC_PARSE_API __declspec(dllimport)
#endif
#ifdef IFC_SCHEMA_EXPORTS
#define IFC_SCHEMA_API __declspec(dllexport)
#else
#define IFC_SCHEMA_API IFC_PARSE_API
#endif
#else // simply assume *nix + GCC-like compiler
#define IFC_PARSE_API __attribute__((visibility("default")))
#define IFC_SCHEMA_API __attribute__((visibility("default")))
#endif
#endif
+76 -76
View File
@@ -23,43 +23,8 @@
#include <map>
#include <mutex>
#include <set>
#ifdef HAS_SCHEMA_2x3
#include "schemas/Ifc2x3.h"
#endif
#ifdef HAS_SCHEMA_4
#include "schemas/Ifc4.h"
#endif
#ifdef HAS_SCHEMA_4x1
#include "schemas/Ifc4x1.h"
#endif
#ifdef HAS_SCHEMA_4x2
#include "schemas/Ifc4x2.h"
#endif
#ifdef HAS_SCHEMA_4x3_rc1
#include "schemas/Ifc4x3_rc1.h"
#endif
#ifdef HAS_SCHEMA_4x3_rc2
#include "schemas/Ifc4x3_rc2.h"
#endif
#ifdef HAS_SCHEMA_4x3_rc3
#include "schemas/Ifc4x3_rc3.h"
#endif
#ifdef HAS_SCHEMA_4x3_rc4
#include "schemas/Ifc4x3_rc4.h"
#endif
#ifdef HAS_SCHEMA_4x3
#include "schemas/Ifc4x3.h"
#endif
#ifdef HAS_SCHEMA_4x3_tc1
#include "schemas/Ifc4x3_tc1.h"
#endif
#ifdef HAS_SCHEMA_4x3_add1
#include "schemas/Ifc4x3_add1.h"
#endif
#ifdef HAS_SCHEMA_4x3_add2
#include "schemas/Ifc4x3_add2.h"
#endif
#include "schemas/Header_section_schema.h"
bool ifcopenshell::declaration::is(const std::string& name) const {
@@ -130,6 +95,8 @@ ifcopenshell::entity::~entity() {
}
}
namespace {
constexpr const char* schema_plugin_prefix = "parse.schema.";
std::string schema_key(const std::string& schema_name) {
return boost::to_upper_copy(schema_name);
}
@@ -144,42 +111,28 @@ namespace {
void register_builtin_schemas(ifcopenshell::schema_registry& registry) {
registry.bind("HEADER_SECTION_SCHEMA", &Header_section_schema::get_schema, &Header_section_schema::clear_schema, builtin_schema_module("HEADER_SECTION_SCHEMA"));
#ifdef HAS_SCHEMA_2x3
registry.bind("IFC2X3", &Ifc2x3::get_schema, &Ifc2x3::clear_schema, builtin_schema_module("IFC2X3"));
#endif
#ifdef HAS_SCHEMA_4
registry.bind("IFC4", &Ifc4::get_schema, &Ifc4::clear_schema, builtin_schema_module("IFC4"));
#endif
#ifdef HAS_SCHEMA_4x1
registry.bind("IFC4X1", &Ifc4x1::get_schema, &Ifc4x1::clear_schema, builtin_schema_module("IFC4X1"));
#endif
#ifdef HAS_SCHEMA_4x2
registry.bind("IFC4X2", &Ifc4x2::get_schema, &Ifc4x2::clear_schema, builtin_schema_module("IFC4X2"));
#endif
#ifdef HAS_SCHEMA_4x3_rc1
registry.bind("IFC4X3_RC1", &Ifc4x3_rc1::get_schema, &Ifc4x3_rc1::clear_schema, builtin_schema_module("IFC4X3_RC1"));
#endif
#ifdef HAS_SCHEMA_4x3_rc2
registry.bind("IFC4X3_RC2", &Ifc4x3_rc2::get_schema, &Ifc4x3_rc2::clear_schema, builtin_schema_module("IFC4X3_RC2"));
#endif
#ifdef HAS_SCHEMA_4x3_rc3
registry.bind("IFC4X3_RC3", &Ifc4x3_rc3::get_schema, &Ifc4x3_rc3::clear_schema, builtin_schema_module("IFC4X3_RC3"));
#endif
#ifdef HAS_SCHEMA_4x3_rc4
registry.bind("IFC4X3_RC4", &Ifc4x3_rc4::get_schema, &Ifc4x3_rc4::clear_schema, builtin_schema_module("IFC4X3_RC4"));
#endif
#ifdef HAS_SCHEMA_4x3
registry.bind("IFC4X3", &Ifc4x3::get_schema, &Ifc4x3::clear_schema, builtin_schema_module("IFC4X3"));
#endif
#ifdef HAS_SCHEMA_4x3_tc1
registry.bind("IFC4X3_TC1", &Ifc4x3_tc1::get_schema, &Ifc4x3_tc1::clear_schema, builtin_schema_module("IFC4X3_TC1"));
#endif
#ifdef HAS_SCHEMA_4x3_add1
registry.bind("IFC4X3_ADD1", &Ifc4x3_add1::get_schema, &Ifc4x3_add1::clear_schema, builtin_schema_module("IFC4X3_ADD1"));
#endif
#ifdef HAS_SCHEMA_4x3_add2
registry.bind("IFC4X3_ADD2", &Ifc4x3_add2::get_schema, &Ifc4x3_add2::clear_schema, builtin_schema_module("IFC4X3_ADD2"));
#endif
}
bool load_schema_plugin(ifcopenshell::schema_registry& registry, const std::string& schema_name) {
ifcopenshell::plugin::manager manager;
manager.add_search_path(ifcopenshell::schema_plugin_directory());
const auto expected_key = schema_key(schema_name);
const auto basename = std::string(schema_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::parse_schema ||
schema_key(module.meta().schema) != expected_key) {
continue;
}
auto register_plugin = module.get_alias<ifcopenshell::schema_registry::register_schema_plugin_fn>(ifcopenshell::schema_plugin_registration_symbol());
register_plugin(registry, module);
return true;
}
return false;
}
}
@@ -225,6 +178,37 @@ ifcopenshell::schema_registry& ifcopenshell::schema_registry_instance() {
return registry;
}
const char* ifcopenshell::schema_plugin_registration_symbol() {
return "ifcopenshell_register_schema_plugin_v1";
}
ifcopenshell::plugin::metadata ifcopenshell::schema_plugin_metadata(const std::string& schema_name) {
plugin::metadata metadata;
metadata.kind_ = plugin::kind::parse_schema;
metadata.id = schema_plugin_prefix + boost::to_lower_copy(schema_name);
metadata.schema = boost::to_upper_copy(schema_name);
return metadata;
}
std::filesystem::path ifcopenshell::schema_plugin_directory() {
return plugin::module_directory(reinterpret_cast<const void*>(&ifcopenshell::load_schema_plugins));
}
void ifcopenshell::load_schema_plugins(schema_registry& registry) {
plugin::manager manager;
manager.add_search_path(schema_plugin_directory());
for (const auto& path : manager.discover(schema_plugin_prefix)) {
auto module = manager.load(path);
if (module.meta().kind_ != plugin::kind::parse_schema) {
continue;
}
auto register_plugin = module.get_alias<schema_registry::register_schema_plugin_fn>(schema_plugin_registration_symbol());
register_plugin(registry, module);
}
}
void ifcopenshell::schema_registry::bind(const std::string& schema_name, get_schema_fn get, clear_schema_fn clear, const plugin::module& module) {
auto& entry = entries_[schema_key(schema_name)];
entry.get_ = get;
@@ -238,7 +222,12 @@ void ifcopenshell::schema_registry::bind(schema_definition* schema) {
}
const ifcopenshell::schema_definition* ifcopenshell::schema_registry::get(const std::string& schema_name) {
auto iter = entries_.find(schema_key(schema_name));
const auto key = schema_key(schema_name);
auto iter = entries_.find(key);
if (iter == entries_.end()) {
load_schema_plugin(*this, schema_name);
iter = entries_.find(key);
}
if (iter == entries_.end()) {
throw ifcopenshell::exception("No schema named " + schema_name);
}
@@ -251,11 +240,22 @@ const ifcopenshell::schema_definition* ifcopenshell::schema_registry::get(const
return iter->second.schema_;
}
std::vector<std::string> ifcopenshell::schema_registry::names() const {
std::vector<std::string> names;
std::vector<std::string> ifcopenshell::schema_registry::names() {
std::set<std::string> seen;
for (const auto& pair : entries_) {
names.push_back(pair.first);
seen.insert(pair.first);
}
plugin::manager manager;
manager.add_search_path(schema_plugin_directory());
for (const auto& path : manager.discover(schema_plugin_prefix)) {
auto module = manager.load(path);
if (module.meta().kind_ == plugin::kind::parse_schema && !module.meta().schema.empty()) {
seen.insert(schema_key(module.meta().schema));
}
}
std::vector<std::string> names(seen.begin(), seen.end());
return names;
}
+10 -1
View File
@@ -504,11 +504,12 @@ class IFC_PARSE_API schema_registry {
public:
typedef const schema_definition& (*get_schema_fn)();
typedef void (*clear_schema_fn)();
typedef void register_schema_plugin_fn(schema_registry&, const ifcopenshell::plugin::module&);
void bind(const std::string& schema_name, get_schema_fn get, clear_schema_fn clear, const ifcopenshell::plugin::module& module = ifcopenshell::plugin::module());
void bind(schema_definition* schema);
const schema_definition* get(const std::string& schema_name);
std::vector<std::string> names() const;
std::vector<std::string> names();
void clear();
private:
@@ -524,6 +525,14 @@ class IFC_PARSE_API schema_registry {
IFC_PARSE_API schema_registry& schema_registry_instance();
IFC_PARSE_API const char* schema_plugin_registration_symbol();
IFC_PARSE_API ifcopenshell::plugin::metadata schema_plugin_metadata(const std::string& schema_name);
IFC_PARSE_API std::filesystem::path schema_plugin_directory();
IFC_PARSE_API void load_schema_plugins(schema_registry& registry);
IFC_PARSE_API const schema_definition* schema_by_name(const std::string& schema_name);
IFC_PARSE_API std::vector<std::string> schema_names();
+58
View File
@@ -0,0 +1,58 @@
/********************************************************************************
* *
* This file is part of IfcOpenShell. *
* *
* IfcOpenShell is free software: you can redistribute it and/or modify *
* it under the terms of the Lesser GNU General Public License as published by *
* the Free Software Foundation, either version 3.0 of the License, or *
* (at your option) any later version. *
* *
* IfcOpenShell is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* Lesser GNU General Public License for more details. *
* *
* You should have received a copy of the Lesser GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* *
********************************************************************************/
// This file was generated with the assistance of an AI coding tool.
#include "schema.h"
#include "hierarchy_helper.h"
#include "macros.h"
#include "si_prefix.h"
#define INCLUDE_SCHEMA(x) STRINGIFY(schemas/x.h)
#include INCLUDE_SCHEMA(IfcSchema)
#undef INCLUDE_SCHEMA
#include <boost/dll/alias.hpp>
namespace ifcopenshell {
namespace schema_plugin {
plugin::abi_info plugin_abi() {
return plugin::host_abi();
}
plugin::metadata plugin_metadata() {
return schema_plugin_metadata(IfcSchema::Identifier);
}
void register_plugin(schema_registry& registry, const plugin::module& module) {
registry.bind(IfcSchema::Identifier, &IfcSchema::get_schema, &IfcSchema::clear_schema, module);
}
}
}
template IFC_SCHEMA_API double ifcopenshell::get_SI_equivalent<IfcSchema>(const IfcSchema::IfcNamedUnit&);
#include "hierarchy_helper.i"
BOOST_DLL_ALIAS(ifcopenshell::schema_plugin::plugin_abi, ifcopenshell_plugin_abi_v1)
BOOST_DLL_ALIAS(ifcopenshell::schema_plugin::plugin_metadata, ifcopenshell_plugin_metadata_v1)
BOOST_DLL_ALIAS(ifcopenshell::schema_plugin::register_plugin, ifcopenshell_register_schema_plugin_v1)
File diff suppressed because it is too large Load Diff
+1175 -1175
View File
File diff suppressed because it is too large Load Diff
+1203 -1203
View File
File diff suppressed because it is too large Load Diff
+1225 -1225
View File
File diff suppressed because it is too large Load Diff
+1313 -1313
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
-144
View File
@@ -18,44 +18,6 @@
********************************************************************************/
#include "si_prefix.h"
#include "instance_data.h"
#ifdef HAS_SCHEMA_2x3
#include "schemas/Ifc2x3.h"
#endif
#ifdef HAS_SCHEMA_4
#include "schemas/Ifc4.h"
#endif
#ifdef HAS_SCHEMA_4x1
#include "schemas/Ifc4x1.h"
#endif
#ifdef HAS_SCHEMA_4x2
#include "schemas/Ifc4x2.h"
#endif
#ifdef HAS_SCHEMA_4x3_rc1
#include "schemas/Ifc4x3_rc1.h"
#endif
#ifdef HAS_SCHEMA_4x3_rc2
#include "schemas/Ifc4x3_rc2.h"
#endif
#ifdef HAS_SCHEMA_4x3_rc3
#include "schemas/Ifc4x3_rc3.h"
#endif
#ifdef HAS_SCHEMA_4x3_rc4
#include "schemas/Ifc4x3_rc4.h"
#endif
#ifdef HAS_SCHEMA_4x3
#include "schemas/Ifc4x3.h"
#endif
#ifdef HAS_SCHEMA_4x3_tc1
#include "schemas/Ifc4x3_tc1.h"
#endif
#ifdef HAS_SCHEMA_4x3_add1
#include "schemas/Ifc4x3_add1.h"
#endif
#ifdef HAS_SCHEMA_4x3_add2
#include "schemas/Ifc4x3_add2.h"
#endif
double ifcopenshell::si_prefix_to_value(const std::string& prefix) {
if (prefix == "EXA") {
@@ -108,109 +70,3 @@ double ifcopenshell::si_prefix_to_value(const std::string& prefix) {
}
return 1.;
}
template <typename Schema>
double ifcopenshell::get_SI_equivalent(const typename Schema::IfcNamedUnit& named_unit) {
double scale = 1.;
typename Schema::IfcSIUnit si_unit;
if (auto conv_unit = named_unit.template as<typename Schema::IfcConversionBasedUnit>()) {
auto factor = conv_unit.ConversionFactor();
auto component = factor.UnitComponent();
if (si_unit = component.concrete().template as<typename Schema::IfcSIUnit>()) {
auto value = factor.ValueComponent();
scale = value.get_attribute_value(0);
}
} else {
si_unit = named_unit.template as<typename Schema::IfcSIUnit>();
}
if (si_unit) {
if (si_unit.Prefix()) {
scale *= si_prefix_to_value(Schema::IfcSIPrefix::ToString(*si_unit.Prefix()));
}
} else {
scale = 0.;
}
return scale;
}
#if defined(_MSC_VER) && _MSC_VER < 1900
#ifdef HAS_SCHEMA_2x3
template double IFC_PARSE_API ifcopenshell::get_SI_equivalent<Ifc2x3>(const Ifc2x3::IfcNamedUnit& named_unit);
#endif
#ifdef HAS_SCHEMA_4
template double IFC_PARSE_API ifcopenshell::get_SI_equivalent<Ifc4>(const Ifc4::IfcNamedUnit& named_unit);
#endif
#ifdef HAS_SCHEMA_4x1
template double IFC_PARSE_API ifcopenshell::get_SI_equivalent<Ifc4x1>(const Ifc4x1::IfcNamedUnit& named_unit);
#endif
#ifdef HAS_SCHEMA_4x2
template double IFC_PARSE_API ifcopenshell::get_SI_equivalent<Ifc4x2>(const Ifc4x2::IfcNamedUnit& named_unit);
#endif
#ifdef HAS_SCHEMA_4x3_rc1
template double IFC_PARSE_API ifcopenshell::get_SI_equivalent<Ifc4x3_rc1>(const Ifc4x3_rc1::IfcNamedUnit& named_unit);
#endif
#ifdef HAS_SCHEMA_4x3_rc2
template double IFC_PARSE_API ifcopenshell::get_SI_equivalent<Ifc4x3_rc2>(const Ifc4x3_rc2::IfcNamedUnit& named_unit);
#endif
#ifdef HAS_SCHEMA_4x3_rc3
template double IFC_PARSE_API ifcopenshell::get_SI_equivalent<Ifc4x3_rc3>(const Ifc4x3_rc3::IfcNamedUnit& named_unit);
#endif
#ifdef HAS_SCHEMA_4x3_rc4
template double IFC_PARSE_API ifcopenshell::get_SI_equivalent<Ifc4x3_rc4>(const Ifc4x3_rc4::IfcNamedUnit& named_unit);
#endif
#ifdef HAS_SCHEMA_4x3
template double IFC_PARSE_API ifcopenshell::get_SI_equivalent<Ifc4x3>(const Ifc4x3::IfcNamedUnit& named_unit);
#endif
#ifdef HAS_SCHEMA_4x3_tc1
template double IFC_PARSE_API ifcopenshell::get_SI_equivalent<Ifc4x3_tc1>(const Ifc4x3_tc1::IfcNamedUnit& named_unit);
#endif
#ifdef HAS_SCHEMA_4x3_add1
template double IFC_PARSE_API ifcopenshell::get_SI_equivalent<Ifc4x3_add1>(const Ifc4x3_add1::IfcNamedUnit& named_unit);
#endif
#ifdef HAS_SCHEMA_4x3_add2
template double IFC_PARSE_API ifcopenshell::get_SI_equivalent<Ifc4x3_add2>(const Ifc4x3_add2::IfcNamedUnit& named_unit);
#endif
#else
#ifdef HAS_SCHEMA_2x3
template double IFC_PARSE_API ifcopenshell::get_SI_equivalent<Ifc2x3>(const typename Ifc2x3::IfcNamedUnit& named_unit);
#endif
#ifdef HAS_SCHEMA_4
template double IFC_PARSE_API ifcopenshell::get_SI_equivalent<Ifc4>(const typename Ifc4::IfcNamedUnit& named_unit);
#endif
#ifdef HAS_SCHEMA_4x1
template double IFC_PARSE_API ifcopenshell::get_SI_equivalent<Ifc4x1>(const typename Ifc4x1::IfcNamedUnit& named_unit);
#endif
#ifdef HAS_SCHEMA_4x2
template double IFC_PARSE_API ifcopenshell::get_SI_equivalent<Ifc4x2>(const typename Ifc4x2::IfcNamedUnit& named_unit);
#endif
#ifdef HAS_SCHEMA_4x3_rc1
template double IFC_PARSE_API ifcopenshell::get_SI_equivalent<Ifc4x3_rc1>(const typename Ifc4x3_rc1::IfcNamedUnit& named_unit);
#endif
#ifdef HAS_SCHEMA_4x3_rc2
template double IFC_PARSE_API ifcopenshell::get_SI_equivalent<Ifc4x3_rc2>(const typename Ifc4x3_rc2::IfcNamedUnit& named_unit);
#endif
#ifdef HAS_SCHEMA_4x3_rc3
template double IFC_PARSE_API ifcopenshell::get_SI_equivalent<Ifc4x3_rc3>(const typename Ifc4x3_rc3::IfcNamedUnit& named_unit);
#endif
#ifdef HAS_SCHEMA_4x3_rc4
template double IFC_PARSE_API ifcopenshell::get_SI_equivalent<Ifc4x3_rc4>(const typename Ifc4x3_rc4::IfcNamedUnit& named_unit);
#endif
#ifdef HAS_SCHEMA_4x3
template double IFC_PARSE_API ifcopenshell::get_SI_equivalent<Ifc4x3>(const typename Ifc4x3::IfcNamedUnit& named_unit);
#endif
#ifdef HAS_SCHEMA_4x3_tc1
template double IFC_PARSE_API ifcopenshell::get_SI_equivalent<Ifc4x3_tc1>(const typename Ifc4x3_tc1::IfcNamedUnit& named_unit);
#endif
#ifdef HAS_SCHEMA_4x3_add1
template double IFC_PARSE_API ifcopenshell::get_SI_equivalent<Ifc4x3_add1>(const typename Ifc4x3_add1::IfcNamedUnit& named_unit);
#endif
#ifdef HAS_SCHEMA_4x3_add2
template double IFC_PARSE_API ifcopenshell::get_SI_equivalent<Ifc4x3_add2>(const typename Ifc4x3_add2::IfcNamedUnit& named_unit);
#endif
#endif
+24 -1
View File
@@ -28,7 +28,30 @@ namespace ifcopenshell {
IFC_PARSE_API double si_prefix_to_value(const std::string& prefix);
template <typename Schema>
IFC_PARSE_API double get_SI_equivalent(const typename Schema::IfcNamedUnit& unit);
double get_SI_equivalent(const typename Schema::IfcNamedUnit& named_unit) {
double scale = 1.;
typename Schema::IfcSIUnit si_unit;
if (auto conv_unit = named_unit.template as<typename Schema::IfcConversionBasedUnit>()) {
auto factor = conv_unit.ConversionFactor();
auto component = factor.UnitComponent();
if (si_unit = component.concrete().template as<typename Schema::IfcSIUnit>()) {
auto value = factor.ValueComponent();
scale = value.get_attribute_value(0);
}
} else {
si_unit = named_unit.template as<typename Schema::IfcSIUnit>();
}
if (si_unit) {
if (si_unit.Prefix()) {
scale *= si_prefix_to_value(Schema::IfcSIPrefix::ToString(*si_unit.Prefix()));
}
} else {
scale = 0.;
}
return scale;
}
} // namespace ifcopenshell
#endif
+3 -3
View File
@@ -121,7 +121,6 @@ endif()
target_link_libraries(ifcopenshell_wrapper PRIVATE Python::Module)
if(WITH_ROCKSDB)
message(STATUS TK)
target_link_libraries(ifcopenshell_wrapper PRIVATE document_serializer_rdb)
endif()
SET_PROPERTY(TARGET ifcopenshell_wrapper PROPERTY SWIG_DEPENDS ${IFCOPENSHELL_LIBRARIES})
@@ -146,8 +145,8 @@ if (WASM_BUILD)
)
endif()
target_link_libraries(ifcopenshell_wrapper PRIVATE IfcGeom IfcParse ${Boost_LIBRARIES} ${LIBSVGFILL})
if(kernel_libraries OR tree_libraries OR mapping_libraries OR geometry_serializer_libraries OR document_serializer_libraries)
add_dependencies(ifcopenshell_wrapper ${kernel_libraries} ${tree_libraries} ${mapping_libraries} ${geometry_serializer_libraries} ${document_serializer_libraries})
if(schema_libraries OR kernel_libraries OR tree_libraries OR mapping_libraries OR geometry_serializer_libraries OR document_serializer_libraries)
add_dependencies(ifcopenshell_wrapper ${schema_libraries} ${kernel_libraries} ${tree_libraries} ${mapping_libraries} ${geometry_serializer_libraries} ${document_serializer_libraries})
endif()
if(NOT WIN32)
SET_INSTALL_RPATHS(ifcopenshell_wrapper "${IFCDIRS};${OCC_LIBRARY_DIR}")
@@ -216,6 +215,7 @@ IF(Python_Interpreter_FOUND OR PYTHON_MODULE_INSTALL_DIR)
set(_ifcopenshell_python_runtime_targets
IfcGeom
IfcParse
${schema_libraries}
${kernel_libraries}
${tree_libraries}
${mapping_libraries}
+1 -1
View File
@@ -208,7 +208,7 @@ private:
std::vector<int> _get_inverse_indices(const express::Base& e) {
if (auto e_ = e.as<express::Entity>()) {
return $self->get_inverse_indices(e_.id());
return $self->get_inverse_indices_by_id(e_.id());
}
throw ifcopenshell::exception("Only entities with ids are supported for get_inverse_indices. Provided entity: '" + e.declaration().name() + "'.");
}
+65 -4
View File
@@ -68,6 +68,35 @@ namespace {
return true;
#endif
}
std::string decorated_basename(const std::string& basename) {
return boost::algorithm::istarts_with(basename, "ifcopenshell.") ? basename : "ifcopenshell." + basename;
}
std::vector<std::string> platform_basenames(const std::string& basename) {
const auto decorated = decorated_basename(basename);
return {
decorated,
"lib" + decorated
};
}
#ifdef _WIN32
struct dll_error_mode_guard {
DWORD previous_ = 0;
bool changed_ = false;
dll_error_mode_guard() {
changed_ = SetThreadErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX, &previous_) != 0;
}
~dll_error_mode_guard() {
if (changed_) {
SetThreadErrorMode(previous_, nullptr);
}
}
};
#endif
}
struct ifcopenshell::plugin::module::data {
@@ -130,7 +159,7 @@ const std::vector<std::filesystem::path>& ifcopenshell::plugin::manager::search_
std::vector<std::filesystem::path> ifcopenshell::plugin::manager::discover(const std::string& basename_prefix) const {
std::vector<std::filesystem::path> result;
const auto suffix = boost::dll::shared_library::suffix().string();
const auto prefixed_basename = "lib" + basename_prefix;
const auto basename_prefixes = platform_basenames(basename_prefix);
for (const auto& search_path : search_paths_) {
if (!std::filesystem::exists(search_path) || !std::filesystem::is_directory(search_path)) {
@@ -146,8 +175,11 @@ std::vector<std::filesystem::path> ifcopenshell::plugin::manager::discover(const
if (!boost::algorithm::iends_with(filename, suffix)) {
continue;
}
if (!boost::algorithm::istarts_with(filename, basename_prefix) &&
!boost::algorithm::istarts_with(filename, prefixed_basename)) {
const auto basename = filename.substr(0, filename.size() - suffix.size());
if (!std::any_of(basename_prefixes.begin(), basename_prefixes.end(), [&basename](const std::string& prefix) {
return boost::algorithm::istarts_with(basename, prefix);
})) {
continue;
}
@@ -160,8 +192,37 @@ std::vector<std::filesystem::path> ifcopenshell::plugin::manager::discover(const
return result;
}
std::vector<std::filesystem::path> ifcopenshell::plugin::manager::discover_exact(const std::string& basename) const {
std::vector<std::filesystem::path> result;
const auto suffix = boost::dll::shared_library::suffix().string();
const auto basename_candidates = platform_basenames(basename);
for (const auto& search_path : search_paths_) {
if (!std::filesystem::exists(search_path) || !std::filesystem::is_directory(search_path)) {
continue;
}
for (const auto& candidate : basename_candidates) {
const auto path = search_path / (candidate + suffix);
if (std::filesystem::is_regular_file(path)) {
result.push_back(path);
}
}
}
std::sort(result.begin(), result.end());
result.erase(std::unique(result.begin(), result.end()), result.end());
return result;
}
ifcopenshell::plugin::module ifcopenshell::plugin::manager::load(const std::filesystem::path& path) const {
auto library = std::make_shared<boost::dll::shared_library>(path, boost::dll::load_mode::default_mode);
#ifdef _WIN32
dll_error_mode_guard error_mode_guard;
const auto load_mode = boost::dll::load_mode::load_with_altered_search_path;
#else
const auto load_mode = boost::dll::load_mode::default_mode;
#endif
auto library = std::make_shared<boost::dll::shared_library>(path, load_mode);
auto abi = library->get_alias<plugin_abi_fn>("ifcopenshell_plugin_abi_v1")();
validate_abi(abi);
auto metadata = library->get_alias<plugin_metadata_fn>("ifcopenshell_plugin_metadata_v1")();
+1
View File
@@ -94,6 +94,7 @@ public:
const std::vector<std::filesystem::path>& search_paths() const;
std::vector<std::filesystem::path> discover(const std::string& basename_prefix) const;
std::vector<std::filesystem::path> discover_exact(const std::string& basename) const;
module load(const std::filesystem::path& path) const;
private:
+3 -3
View File
@@ -17,7 +17,7 @@ function(add_document_serializer_plugin target output_name)
target_compile_definitions(${target} PRIVATE SERIALIZERS_EXPORTS BOOST_DLL_USE_STD_FS ${PLUGIN_DEFINITIONS})
target_link_libraries(${target} PRIVATE ${plugin_when_not_wasm} IfcGeom IfcParse ${PLUGIN_LIBRARIES})
set_target_properties(${target} PROPERTIES
OUTPUT_NAME "${output_name}"
OUTPUT_NAME "ifcopenshell.${output_name}"
RUNTIME_OUTPUT_DIRECTORY "${document_serializer_plugin_runtime_dir}"
LIBRARY_OUTPUT_DIRECTORY "${document_serializer_plugin_runtime_dir}"
)
@@ -43,7 +43,7 @@ function(add_geometry_serializer_plugin target output_name)
target_link_libraries(${target} PRIVATE proj::proj)
endif()
set_target_properties(${target} PROPERTIES
OUTPUT_NAME "${output_name}"
OUTPUT_NAME "ifcopenshell.${output_name}"
RUNTIME_OUTPUT_DIRECTORY "${geometry_serializer_plugin_runtime_dir}"
LIBRARY_OUTPUT_DIRECTORY "${geometry_serializer_plugin_runtime_dir}"
)
@@ -90,7 +90,7 @@ if(WITH_OPENCASCADE AND NOT WASM_BUILD)
add_geometry_serializer_plugin(geometry_serializer_svg "geometry.svg" SOURCES geometry_svg_plugin.cpp SvgSerializer.cpp util.cpp LIBRARIES ${opencascade_geometry_serializer_libraries})
if(HDF5_SUPPORT)
add_geometry_serializer_plugin(geometry_serializer_hdf "geometry.hdf" SOURCES geometry_hdf_plugin.cpp HdfSerializer.cpp LIBRARIES ${opencascade_geometry_serializer_libraries} ${HDF5_LIBRARIES})
add_geometry_serializer_plugin(geometry_serializer_hdf "geometry.h5" SOURCES geometry_hdf_plugin.cpp HdfSerializer.cpp LIBRARIES ${opencascade_geometry_serializer_libraries} ${HDF5_LIBRARIES})
endif()
endif()
+75 -2
View File
@@ -107,14 +107,24 @@ const ifcopenshell::serializers::document_serializer_registry::entry* ifcopenshe
}
const ifcopenshell::serializers::document_serializer_info* ifcopenshell::serializers::document_serializer_registry::find(const std::string& format, const std::string& schema_name) const {
auto* registry = const_cast<document_serializer_registry*>(this);
const auto* entry = find_entry_(format, schema_name);
if (!entry) {
load_document_serializer_plugin(*registry, format, schema_name);
entry = find_entry_(format, schema_name);
}
return entry ? &entry->info_ : nullptr;
}
boost::shared_ptr<Serializer> ifcopenshell::serializers::document_serializer_registry::create(const std::string& format, const document_serializer_context& context) const {
const auto schema_name = !context.schema_name.empty() ? context.schema_name :
(context.file ? context.file->schema()->name() : std::string());
auto* registry = const_cast<document_serializer_registry*>(this);
const auto* entry = find_entry_(format, schema_name);
if (!entry) {
load_document_serializer_plugin(*registry, format, schema_name);
entry = find_entry_(format, schema_name);
}
if (!entry) {
throw ifcopenshell::exception("No document serializer registered for " + format + (schema_name.empty() ? std::string() : " and schema " + schema_name));
}
@@ -135,6 +145,34 @@ std::vector<ifcopenshell::serializers::document_serializer_info> ifcopenshell::s
}
}
ifcopenshell::plugin::manager manager;
add_document_serializer_search_paths(manager);
for (const auto& path : manager.discover(document_serializer_plugin_prefix())) {
ifcopenshell::plugin::module module;
try {
module = manager.load(path);
} catch (const std::exception& e) {
logger::error(e);
continue;
}
if (module.meta().kind_ != ifcopenshell::plugin::kind::document_serializer) {
continue;
}
document_serializer_registry plugin_registry;
auto register_plugin = module.get_alias<register_document_serializer_plugin_fn>(document_serializer_plugin_registration_symbol());
register_plugin(plugin_registry, module);
for (const auto& pair : plugin_registry.entries_) {
for (const auto& entry : pair.second) {
const auto key = entry.info_.format + "|" + entry.info_.schema_name;
if (!seen.insert(key).second) {
continue;
}
result.push_back(entry.info_);
}
}
}
return result;
}
@@ -179,9 +217,44 @@ void ifcopenshell::serializers::load_document_serializer_plugins(document_serial
}
}
bool ifcopenshell::serializers::load_document_serializer_plugin(document_serializer_registry& registry, const std::string& format, const std::string& schema_name) {
const auto format_key = document_serializer_key(format);
if (format_key.empty()) {
return false;
}
const auto schema_key = document_serializer_schema_key(schema_name);
auto basename = document_serializer_plugin_prefix(format_key);
if (!schema_key.empty()) {
basename += "." + boost::to_lower_copy(schema_key);
}
ifcopenshell::plugin::manager manager;
add_document_serializer_search_paths(manager);
for (const auto& path : manager.discover_exact(basename)) {
ifcopenshell::plugin::module module;
try {
module = manager.load(path);
} catch (const std::exception& e) {
logger::error(e);
continue;
}
if (module.meta().kind_ != ifcopenshell::plugin::kind::document_serializer ||
module.meta().format != format_key ||
document_serializer_schema_key(module.meta().schema) != schema_key) {
continue;
}
auto register_plugin = module.get_alias<register_document_serializer_plugin_fn>(document_serializer_plugin_registration_symbol());
register_plugin(registry, module);
return registry.find_entry_(format_key, schema_key) != nullptr;
}
return false;
}
ifcopenshell::serializers::document_serializer_registry& ifcopenshell::serializers::document_serializer_registry_instance() {
static document_serializer_registry registry;
static std::once_flag once;
std::call_once(once, load_document_serializer_plugins, std::ref(registry));
return registry;
}
@@ -73,6 +73,8 @@ private:
const entry* find_entry_(const std::string& format, const std::string& schema_name) const;
friend SERIALIZERS_API bool load_document_serializer_plugin(document_serializer_registry& registry, const std::string& format, const std::string& schema_name);
std::map<std::string, std::vector<entry>> entries_;
};
@@ -82,6 +84,7 @@ SERIALIZERS_API const char* document_serializer_plugin_registration_symbol();
SERIALIZERS_API ifcopenshell::plugin::metadata document_serializer_plugin_metadata(const std::string& format, const std::string& schema_name = std::string());
SERIALIZERS_API std::filesystem::path document_serializer_plugin_directory();
SERIALIZERS_API void load_document_serializer_plugins(document_serializer_registry& registry);
SERIALIZERS_API bool load_document_serializer_plugin(document_serializer_registry& registry, const std::string& format, const std::string& schema_name = std::string());
SERIALIZERS_API document_serializer_registry& document_serializer_registry_instance();
}
+1 -1
View File
@@ -34,7 +34,7 @@ plugin::abi_info plugin_abi() {
}
plugin::metadata plugin_metadata() {
return geometry_serializer_plugin_metadata("hdf");
return geometry_serializer_plugin_metadata("h5");
}
boost::shared_ptr<GeometrySerializer> create_serializer(const geometry_serializer_context& context) {
+83 -6
View File
@@ -43,6 +43,14 @@ std::string geometry_serializer_key(const std::string& extension) {
return key;
}
std::string geometry_serializer_format_from_extension(const std::string& extension) {
auto key = geometry_serializer_key(extension);
if (!key.empty() && key.front() == '.') {
key.erase(key.begin());
}
return key;
}
void add_geometry_serializer_search_paths(ifcopenshell::plugin::manager& manager) {
const auto directory = ifcopenshell::serializers::geometry_serializer_plugin_directory();
manager.add_search_path(directory);
@@ -80,11 +88,19 @@ void ifcopenshell::serializers::geometry_serializer_registry::bind(const geometr
}
bool ifcopenshell::serializers::geometry_serializer_registry::has(const std::string& extension) const {
return entries_.find(geometry_serializer_key(extension)) != entries_.end();
const auto key = geometry_serializer_key(extension);
if (entries_.find(key) == entries_.end()) {
load_geometry_serializer_plugin(const_cast<geometry_serializer_registry&>(*this), extension);
}
return entries_.find(key) != entries_.end();
}
const ifcopenshell::serializers::geometry_serializer_info* ifcopenshell::serializers::geometry_serializer_registry::find(const std::string& extension) const {
const auto iter = entries_.find(geometry_serializer_key(extension));
const auto key = geometry_serializer_key(extension);
if (entries_.find(key) == entries_.end()) {
load_geometry_serializer_plugin(const_cast<geometry_serializer_registry&>(*this), extension);
}
const auto iter = entries_.find(key);
if (iter == entries_.end()) {
return nullptr;
}
@@ -92,7 +108,11 @@ const ifcopenshell::serializers::geometry_serializer_info* ifcopenshell::seriali
}
void ifcopenshell::serializers::geometry_serializer_registry::configure(const std::string& extension, geometry_serializer_context& context) const {
const auto iter = entries_.find(geometry_serializer_key(extension));
const auto key = geometry_serializer_key(extension);
if (entries_.find(key) == entries_.end()) {
load_geometry_serializer_plugin(const_cast<geometry_serializer_registry&>(*this), extension);
}
const auto iter = entries_.find(key);
if (iter == entries_.end()) {
throw ifcopenshell::exception("No geometry serializer registered for " + extension);
}
@@ -102,7 +122,11 @@ void ifcopenshell::serializers::geometry_serializer_registry::configure(const st
}
boost::shared_ptr<GeometrySerializer> ifcopenshell::serializers::geometry_serializer_registry::create(const std::string& extension, const geometry_serializer_context& context) const {
const auto iter = entries_.find(geometry_serializer_key(extension));
const auto key = geometry_serializer_key(extension);
if (entries_.find(key) == entries_.end()) {
load_geometry_serializer_plugin(const_cast<geometry_serializer_registry&>(*this), extension);
}
const auto iter = entries_.find(key);
if (iter == entries_.end()) {
throw ifcopenshell::exception("No geometry serializer registered for " + extension);
}
@@ -118,6 +142,31 @@ std::vector<ifcopenshell::serializers::geometry_serializer_info> ifcopenshell::s
}
result.push_back(pair.second.info_);
}
ifcopenshell::plugin::manager manager;
add_geometry_serializer_search_paths(manager);
for (const auto& path : manager.discover(geometry_serializer_plugin_prefix())) {
ifcopenshell::plugin::module module;
try {
module = manager.load(path);
} catch (const std::exception& e) {
logger::error(e);
continue;
}
if (module.meta().kind_ != ifcopenshell::plugin::kind::geometry_serializer) {
continue;
}
geometry_serializer_registry plugin_registry;
auto register_plugin = module.get_alias<register_geometry_serializer_plugin_fn>(geometry_serializer_plugin_registration_symbol());
register_plugin(plugin_registry, module);
for (const auto& pair : plugin_registry.entries_) {
if (!seen_formats.insert(pair.second.info_.format).second) {
continue;
}
result.push_back(pair.second.info_);
}
}
return result;
}
@@ -158,9 +207,37 @@ void ifcopenshell::serializers::load_geometry_serializer_plugins(geometry_serial
}
}
bool ifcopenshell::serializers::load_geometry_serializer_plugin(geometry_serializer_registry& registry, const std::string& extension) {
const auto format = geometry_serializer_format_from_extension(extension);
if (format.empty()) {
return false;
}
ifcopenshell::plugin::manager manager;
add_geometry_serializer_search_paths(manager);
for (const auto& path : manager.discover_exact(geometry_serializer_plugin_prefix(format))) {
ifcopenshell::plugin::module module;
try {
module = manager.load(path);
} catch (const std::exception& e) {
logger::error(e);
continue;
}
if (module.meta().kind_ != ifcopenshell::plugin::kind::geometry_serializer ||
module.meta().format != format) {
continue;
}
auto register_plugin = module.get_alias<register_geometry_serializer_plugin_fn>(geometry_serializer_plugin_registration_symbol());
register_plugin(registry, module);
return registry.entries_.find(geometry_serializer_key(extension)) != registry.entries_.end();
}
return false;
}
ifcopenshell::serializers::geometry_serializer_registry& ifcopenshell::serializers::geometry_serializer_registry_instance() {
static geometry_serializer_registry registry;
static std::once_flag once;
std::call_once(once, load_geometry_serializer_plugins, std::ref(registry));
return registry;
}
@@ -76,6 +76,8 @@ private:
ifcopenshell::plugin::module module_;
};
friend SERIALIZERS_API bool load_geometry_serializer_plugin(geometry_serializer_registry& registry, const std::string& extension);
std::map<std::string, entry> entries_;
};
@@ -85,6 +87,7 @@ SERIALIZERS_API const char* geometry_serializer_plugin_registration_symbol();
SERIALIZERS_API ifcopenshell::plugin::metadata geometry_serializer_plugin_metadata(const std::string& format);
SERIALIZERS_API std::filesystem::path geometry_serializer_plugin_directory();
SERIALIZERS_API void load_geometry_serializer_plugins(geometry_serializer_registry& registry);
SERIALIZERS_API bool load_geometry_serializer_plugin(geometry_serializer_registry& registry, const std::string& extension);
SERIALIZERS_API geometry_serializer_registry& geometry_serializer_registry_instance();
}
@@ -1,10 +1,22 @@
foreach(schema ${SCHEMA_VERSIONS})
add_document_serializer_plugin(document_serializer_xml_ifc${schema} "document.xml.ifc${schema}" SOURCES XmlSerializer.cpp xml_plugin.cpp)
if(NOT WASM_BUILD)
set(schema_plugin_library parse_schema_ifc${schema})
else()
set(schema_plugin_library)
endif()
add_document_serializer_plugin(document_serializer_xml_ifc${schema} "document.xml.ifc${schema}" SOURCES XmlSerializer.cpp xml_plugin.cpp LIBRARIES ${schema_plugin_library})
target_compile_definitions(document_serializer_xml_ifc${schema} PRIVATE IfcSchema=Ifc${schema})
if(WASM_BUILD)
target_link_options(document_serializer_xml_ifc${schema} PRIVATE "SHELL:-s ERROR_ON_UNDEFINED_SYMBOLS=0")
endif()
if(GLTF_SUPPORT)
add_document_serializer_plugin(document_serializer_json_ifc${schema} "document.json.ifc${schema}" SOURCES JsonSerializer.cpp json_plugin.cpp LIBRARIES nlohmann_json::nlohmann_json DEFINITIONS WITH_GLTF)
add_document_serializer_plugin(document_serializer_json_ifc${schema} "document.json.ifc${schema}" SOURCES JsonSerializer.cpp json_plugin.cpp LIBRARIES nlohmann_json::nlohmann_json ${schema_plugin_library} DEFINITIONS WITH_GLTF)
target_compile_definitions(document_serializer_json_ifc${schema} PRIVATE IfcSchema=Ifc${schema})
if(WASM_BUILD)
target_link_options(document_serializer_json_ifc${schema} PRIVATE "SHELL:-s ERROR_ON_UNDEFINED_SYMBOLS=0")
endif()
endif()
endforeach()