mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-30 08:33:10 +00:00
tree and document plug-ins
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
add_subdirectory(mapping)
|
||||
set(mapping_libraries ${mapping_libraries} PARENT_SCOPE)
|
||||
|
||||
# IfcGeom (schema agnostic)
|
||||
file(GLOB SCHEMA_AGNOSTIC_H_FILES *.h)
|
||||
@@ -18,16 +19,18 @@ find_package(Eigen3 REQUIRED)
|
||||
|
||||
add_subdirectory(kernels)
|
||||
set(kernel_libraries ${kernel_libraries} PARENT_SCOPE)
|
||||
set(tree_libraries ${tree_libraries} PARENT_SCOPE)
|
||||
|
||||
if(WASM_BUILD)
|
||||
target_link_libraries(IfcGeom plugin ${Boost_LIBRARIES} ${mapping_libraries} ${CMAKE_THREAD_LIBS_INIT} "Eigen3::Eigen")
|
||||
target_link_libraries(IfcGeom plugin ${Boost_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} "Eigen3::Eigen")
|
||||
else()
|
||||
target_link_libraries(IfcGeom plugin IfcParse ${Boost_LIBRARIES} ${mapping_libraries} ${CMAKE_THREAD_LIBS_INIT} "Eigen3::Eigen")
|
||||
target_link_libraries(IfcGeom plugin IfcParse ${Boost_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} "Eigen3::Eigen")
|
||||
endif()
|
||||
|
||||
if((BUILD_CONVERT OR BUILD_IFCPYTHON) AND WITH_OPENCASCADE)
|
||||
add_subdirectory(Serialization)
|
||||
set(IFCOPENSHELL_LIBRARIES ${IFCOPENSHELL_LIBRARIES} PARENT_SCOPE)
|
||||
set(geometry_serializer_libraries ${geometry_serializer_libraries} PARENT_SCOPE)
|
||||
endif()
|
||||
|
||||
install(FILES ${SCHEMA_AGNOSTIC_H_FILES}
|
||||
|
||||
@@ -58,6 +58,7 @@ struct EdgeKey {
|
||||
}
|
||||
};
|
||||
|
||||
#ifndef SWIG
|
||||
namespace std {
|
||||
template <>
|
||||
struct hash<EdgeKey> {
|
||||
@@ -66,6 +67,7 @@ namespace std {
|
||||
}
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace IfcGeom {
|
||||
|
||||
@@ -73,6 +75,7 @@ namespace IfcGeom {
|
||||
class IFC_GEOM_API Triangulation;
|
||||
}
|
||||
|
||||
#ifndef SWIG
|
||||
template <typename T>
|
||||
constexpr T add_(T a, T b) {
|
||||
return a + b;
|
||||
@@ -107,6 +110,7 @@ namespace IfcGeom {
|
||||
constexpr T negate_(T a) {
|
||||
return -a;
|
||||
}
|
||||
#endif
|
||||
|
||||
class IFC_GEOM_API OpaqueNumber {
|
||||
public:
|
||||
@@ -126,6 +130,7 @@ namespace IfcGeom {
|
||||
};
|
||||
|
||||
// @todo this can simply be a template class, to remove the need for the NumberEpeck in CGAL kernel.
|
||||
#ifndef SWIG
|
||||
class IFC_GEOM_API NumberNativeDouble : public OpaqueNumber {
|
||||
private:
|
||||
double value_;
|
||||
@@ -189,7 +194,24 @@ namespace IfcGeom {
|
||||
return new NumberNativeDouble(value_);
|
||||
}
|
||||
};
|
||||
#else
|
||||
class IFC_GEOM_API NumberNativeDouble : public OpaqueNumber {
|
||||
public:
|
||||
NumberNativeDouble(double v);
|
||||
virtual double to_double() const;
|
||||
virtual std::string to_string() const;
|
||||
virtual OpaqueNumber* operator+(OpaqueNumber* other) const;
|
||||
virtual OpaqueNumber* operator-(OpaqueNumber* other) const;
|
||||
virtual OpaqueNumber* operator*(OpaqueNumber* other) const;
|
||||
virtual OpaqueNumber* operator/(OpaqueNumber* other) const;
|
||||
virtual bool operator==(OpaqueNumber* other) const;
|
||||
virtual bool operator<(OpaqueNumber* other) const;
|
||||
virtual OpaqueNumber* operator-() const;
|
||||
virtual OpaqueNumber* clone() const;
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifndef SWIG
|
||||
template <size_t N>
|
||||
struct IFC_GEOM_API OpaqueCoordinate {
|
||||
private:
|
||||
@@ -251,10 +273,25 @@ namespace IfcGeom {
|
||||
}
|
||||
}
|
||||
};
|
||||
#else
|
||||
template <size_t N>
|
||||
struct IFC_GEOM_API OpaqueCoordinate {
|
||||
OpaqueCoordinate();
|
||||
OpaqueCoordinate(const OpaqueCoordinate& other);
|
||||
OpaqueCoordinate& operator=(const OpaqueCoordinate& other);
|
||||
~OpaqueCoordinate();
|
||||
OpaqueNumber* get(size_t i) const;
|
||||
void set(size_t i, OpaqueNumber* n);
|
||||
};
|
||||
#endif
|
||||
|
||||
class IFC_GEOM_API ConversionResultShape {
|
||||
public:
|
||||
#ifdef SWIG
|
||||
virtual std::string backend_id() const = 0;
|
||||
#else
|
||||
virtual std::string_view backend_id() const = 0;
|
||||
#endif
|
||||
virtual void Triangulate(ifcopenshell::geometry::Settings settings, const ifcopenshell::geometry::taxonomy::matrix4& place, Representation::Triangulation* t, int item_id, int surface_style_id) const = 0;
|
||||
IfcGeom::Representation::Triangulation* Triangulate(const ifcopenshell::geometry::Settings& settings) const;
|
||||
virtual void Serialize(const ifcopenshell::geometry::taxonomy::matrix4& place, std::string&) const = 0;
|
||||
@@ -346,7 +383,7 @@ namespace IfcGeom {
|
||||
|
||||
typedef std::vector<ConversionResult> ConversionResults;
|
||||
|
||||
|
||||
#ifndef SWIG
|
||||
namespace util {
|
||||
// @todo this is now moved to occt kernel, do we need something similar in cgal?
|
||||
// bool flatten_shape_list(const IfcGeom::ConversionResults& shapes, TopoDS_Shape& result, bool fuse, double tol);
|
||||
@@ -424,6 +461,7 @@ namespace IfcGeom {
|
||||
return loops;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,15 +1,20 @@
|
||||
set(geometry_serialization_plugin_runtime_dir "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>")
|
||||
|
||||
add_subdirectory(schema)
|
||||
|
||||
add_library(geometry_serializer Serialization.cpp)
|
||||
add_library(geometry_serializer Serialization.cpp opencascade_geometry_ifc_writer_plugin.cpp)
|
||||
add_library(opencascade_geometry_ifc_writer ALIAS geometry_serializer)
|
||||
set_target_properties(geometry_serializer PROPERTIES COMPILE_FLAGS "-DIFC_GEOMSERIALIZATION_EXPORTS")
|
||||
target_link_libraries(geometry_serializer plugin ${geometry_serializer_libraries} IfcGeom IfcParse)
|
||||
set_target_properties(geometry_serializer PROPERTIES
|
||||
COMPILE_FLAGS "-DIFC_GEOMSERIALIZATION_EXPORTS"
|
||||
RUNTIME_OUTPUT_DIRECTORY "${geometry_serialization_plugin_runtime_dir}"
|
||||
LIBRARY_OUTPUT_DIRECTORY "${geometry_serialization_plugin_runtime_dir}"
|
||||
)
|
||||
target_link_libraries(geometry_serializer plugin IfcGeom IfcParse ${OpenCASCADE_LIBRARIES})
|
||||
target_link_libraries(geometry_serializer geometry_kernel_opencascade)
|
||||
set(IFCOPENSHELL_LIBRARIES ${IFCOPENSHELL_LIBRARIES} "geometry_serializer" ${geometry_serializer_libraries})
|
||||
set(IFCOPENSHELL_LIBRARIES ${IFCOPENSHELL_LIBRARIES} "geometry_serializer")
|
||||
set(IFCOPENSHELL_LIBRARIES ${IFCOPENSHELL_LIBRARIES} PARENT_SCOPE)
|
||||
|
||||
file(GLOB IFCGEOM_SERIALIZATION_H_FILE *.h)
|
||||
install(FILES ${IFCGEOM_SERIALIZATION_H_FILE}
|
||||
install(FILES Serialization.h
|
||||
DESTINATION ${INCLUDEDIR}/ifcgeom/Serialization
|
||||
)
|
||||
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
#include "Serialization.h"
|
||||
#include "opencascade_geometry_ifc_writer_plugin.h"
|
||||
|
||||
#include "../../ifcgeom/kernels/opencascade/OpenCascadeConversionResult.h"
|
||||
#include "../../ifcparse/file.h"
|
||||
|
||||
#include <boost/algorithm/string/case_conv.hpp>
|
||||
#include <boost/preprocessor/stringize.hpp>
|
||||
#include <boost/preprocessor/seq/for_each.hpp>
|
||||
|
||||
#include <mutex>
|
||||
|
||||
@@ -13,55 +12,12 @@ namespace {
|
||||
std::string writer_schema_key(const std::string& schema_name) {
|
||||
return boost::to_upper_copy(schema_name);
|
||||
}
|
||||
|
||||
ifcopenshell::plugin::module builtin_writer_module(const std::string& schema_name) {
|
||||
ifcopenshell::plugin::metadata metadata;
|
||||
metadata.kind_ = ifcopenshell::plugin::kind::opencascade_geometry_ifc_writer;
|
||||
metadata.id = "geometry.ifc_writer." + boost::to_lower_copy(schema_name);
|
||||
metadata.schema = schema_name;
|
||||
return ifcopenshell::plugin::module::builtin(metadata);
|
||||
}
|
||||
|
||||
const ifcopenshell::geometry::OpenCascadeShape& require_opencascade_shape(const IfcGeom::ConversionResultShape& shape) {
|
||||
const auto* oc_shape = dynamic_cast<const ifcopenshell::geometry::OpenCascadeShape*>(&shape);
|
||||
if (!oc_shape) {
|
||||
throw ifcopenshell::exception("OpenCascade geometry IFC writer requires an opencascade conversion result shape");
|
||||
}
|
||||
return *oc_shape;
|
||||
}
|
||||
|
||||
template <express::Base(*Fn)(ifcopenshell::file&, const TopoDS_Shape&, bool)>
|
||||
express::Base serialise_adapter(ifcopenshell::file& f, const IfcGeom::ConversionResultShape& shape, bool advanced) {
|
||||
return Fn(f, require_opencascade_shape(shape).shape(), advanced);
|
||||
}
|
||||
|
||||
template <express::Base(*Fn)(ifcopenshell::file&, const TopoDS_Shape&, double)>
|
||||
express::Base tesselate_adapter(ifcopenshell::file& f, const IfcGeom::ConversionResultShape& shape, double deflection) {
|
||||
return Fn(f, require_opencascade_shape(shape).shape(), deflection);
|
||||
}
|
||||
}
|
||||
|
||||
#define EXTERNAL_TESSELATE(r, data, elem) \
|
||||
express::Base BOOST_PP_CAT(tesselate_Ifc, elem)(ifcopenshell::file&, const TopoDS_Shape& shape, double deflection);
|
||||
|
||||
#define EXTERNAL_SERIALISE(r, data, elem) \
|
||||
express::Base BOOST_PP_CAT(serialise_Ifc, elem)(ifcopenshell::file&, const TopoDS_Shape& shape, bool advanced);
|
||||
|
||||
#define BIND_WRITER(r, data, elem) \
|
||||
registry.bind(BOOST_PP_STRINGIZE(BOOST_PP_CAT(Ifc, elem)), \
|
||||
&serialise_adapter<BOOST_PP_CAT(serialise_Ifc, elem)>, \
|
||||
&tesselate_adapter<BOOST_PP_CAT(tesselate_Ifc, elem)>, \
|
||||
builtin_writer_module(BOOST_PP_STRINGIZE(BOOST_PP_CAT(Ifc, elem))));
|
||||
|
||||
BOOST_PP_SEQ_FOR_EACH(EXTERNAL_TESSELATE, , SCHEMA_SEQ)
|
||||
BOOST_PP_SEQ_FOR_EACH(EXTERNAL_SERIALISE, , SCHEMA_SEQ)
|
||||
|
||||
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, []() {
|
||||
BOOST_PP_SEQ_FOR_EACH(BIND_WRITER, , SCHEMA_SEQ)
|
||||
});
|
||||
std::call_once(once, load_opencascade_geometry_ifc_writer_plugins, std::ref(registry));
|
||||
return registry;
|
||||
}
|
||||
|
||||
@@ -69,7 +25,7 @@ void IfcGeom::opencascade_geometry_ifc_writer_registry::bind(const std::string&
|
||||
entry entry;
|
||||
entry.serialise_ = serialise;
|
||||
entry.tesselate_ = tesselate;
|
||||
entry.module_ = module;
|
||||
entry.module_ = module.meta().id.empty() ? ifcopenshell::plugin::module(opencascade_geometry_ifc_writer_plugin_metadata(schema_name)) : module;
|
||||
entries_[writer_schema_key(schema_name)] = entry;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,9 @@
|
||||
#ifndef IFC_GEOMSERIALIZATION_API_H
|
||||
#define IFC_GEOMSERIALIZATION_API_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef SWIG
|
||||
#define IFC_GEOMSERIALIZATION_API
|
||||
#elif defined(_WIN32)
|
||||
#ifdef IFC_GEOMSERIALIZATION_EXPORTS
|
||||
#define IFC_GEOMSERIALIZATION_API __declspec(dllexport)
|
||||
#else
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#include "opencascade_geometry_ifc_writer_plugin.h"
|
||||
|
||||
#include <boost/algorithm/string/case_conv.hpp>
|
||||
|
||||
namespace {
|
||||
constexpr const char* opencascade_geometry_ifc_writer_plugin_prefix = "geometry.serialization.";
|
||||
}
|
||||
|
||||
const char* IfcGeom::opencascade_geometry_ifc_writer_plugin_registration_symbol() {
|
||||
return "ifcopenshell_register_opencascade_geometry_ifc_writer_plugin_v1";
|
||||
}
|
||||
|
||||
ifcopenshell::plugin::metadata IfcGeom::opencascade_geometry_ifc_writer_plugin_metadata(const std::string& schema_name) {
|
||||
ifcopenshell::plugin::metadata metadata;
|
||||
metadata.kind_ = ifcopenshell::plugin::kind::opencascade_geometry_ifc_writer;
|
||||
metadata.id = opencascade_geometry_ifc_writer_plugin_prefix + boost::to_lower_copy(schema_name);
|
||||
metadata.schema = boost::to_upper_copy(schema_name);
|
||||
return metadata;
|
||||
}
|
||||
|
||||
std::filesystem::path IfcGeom::opencascade_geometry_ifc_writer_plugin_directory() {
|
||||
return ifcopenshell::plugin::module_directory(reinterpret_cast<const void*>(&IfcGeom::load_opencascade_geometry_ifc_writer_plugins));
|
||||
}
|
||||
|
||||
void IfcGeom::load_opencascade_geometry_ifc_writer_plugins(opencascade_geometry_ifc_writer_registry& registry) {
|
||||
ifcopenshell::plugin::manager manager;
|
||||
manager.add_search_path(opencascade_geometry_ifc_writer_plugin_directory());
|
||||
|
||||
for (const auto& path : manager.discover(opencascade_geometry_ifc_writer_plugin_prefix)) {
|
||||
auto module = manager.load(path);
|
||||
if (module.meta().kind_ != ifcopenshell::plugin::kind::opencascade_geometry_ifc_writer) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef IFCOPENSHELL_OPENCASCADE_GEOMETRY_IFC_WRITER_PLUGIN_H
|
||||
#define IFCOPENSHELL_OPENCASCADE_GEOMETRY_IFC_WRITER_PLUGIN_H
|
||||
|
||||
#include "Serialization.h"
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
namespace IfcGeom {
|
||||
|
||||
typedef void register_opencascade_geometry_ifc_writer_plugin_fn(opencascade_geometry_ifc_writer_registry&, const ifcopenshell::plugin::module&);
|
||||
|
||||
IFC_GEOMSERIALIZATION_API const char* opencascade_geometry_ifc_writer_plugin_registration_symbol();
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,7 +1,12 @@
|
||||
foreach(schema ${SCHEMA_VERSIONS})
|
||||
add_library(geometry_serializer_ifc${schema} STATIC Serialization.cpp)
|
||||
target_link_libraries(geometry_serializer_ifc${schema} ${OpenCASCADE_LIBRARIES})
|
||||
set_target_properties(geometry_serializer_ifc${schema} PROPERTIES COMPILE_FLAGS "-DIFC_GEOMSERIALIZATION_EXPORTS -DIfcSchema=Ifc${schema}")
|
||||
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})
|
||||
set_target_properties(geometry_serializer_ifc${schema} PROPERTIES
|
||||
COMPILE_FLAGS "-DIfcSchema=Ifc${schema}"
|
||||
OUTPUT_NAME "geometry.serialization.ifc${schema}"
|
||||
RUNTIME_OUTPUT_DIRECTORY "${geometry_serialization_plugin_runtime_dir}"
|
||||
LIBRARY_OUTPUT_DIRECTORY "${geometry_serialization_plugin_runtime_dir}"
|
||||
)
|
||||
list(APPEND geometry_serializer_libraries geometry_serializer_ifc${schema})
|
||||
endforeach()
|
||||
set(geometry_serializer_libraries ${geometry_serializer_libraries} PARENT_SCOPE)
|
||||
set(geometry_serializer_libraries ${geometry_serializer_libraries} PARENT_SCOPE)
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#include "../opencascade_geometry_ifc_writer_plugin.h"
|
||||
|
||||
#include "../../../ifcgeom/kernels/opencascade/OpenCascadeConversionResult.h"
|
||||
#include "../../../ifcparse/exception.h"
|
||||
#include "../../../ifcparse/macros.h"
|
||||
|
||||
#include <boost/dll/alias.hpp>
|
||||
|
||||
express::Base POSTFIX_SCHEMA(serialise)(ifcopenshell::file& f, const TopoDS_Shape& shape, bool advanced);
|
||||
express::Base POSTFIX_SCHEMA(tesselate)(ifcopenshell::file& f, const TopoDS_Shape& shape, double deflection);
|
||||
|
||||
namespace {
|
||||
const ifcopenshell::geometry::OpenCascadeShape& require_opencascade_shape(const IfcGeom::ConversionResultShape& shape) {
|
||||
const auto* oc_shape = dynamic_cast<const ifcopenshell::geometry::OpenCascadeShape*>(&shape);
|
||||
if (!oc_shape) {
|
||||
throw ifcopenshell::exception("OpenCascade geometry IFC writer requires an opencascade conversion result shape");
|
||||
}
|
||||
return *oc_shape;
|
||||
}
|
||||
|
||||
express::Base serialise_adapter(ifcopenshell::file& f, const IfcGeom::ConversionResultShape& shape, bool advanced) {
|
||||
return POSTFIX_SCHEMA(serialise)(f, require_opencascade_shape(shape).shape(), advanced);
|
||||
}
|
||||
|
||||
express::Base tesselate_adapter(ifcopenshell::file& f, const IfcGeom::ConversionResultShape& shape, double deflection) {
|
||||
return POSTFIX_SCHEMA(tesselate)(f, require_opencascade_shape(shape).shape(), deflection);
|
||||
}
|
||||
}
|
||||
|
||||
namespace IfcGeom {
|
||||
namespace opencascade_geometry_ifc_writer_plugin {
|
||||
|
||||
ifcopenshell::plugin::abi_info plugin_abi() {
|
||||
return ifcopenshell::plugin::host_abi();
|
||||
}
|
||||
|
||||
ifcopenshell::plugin::metadata plugin_metadata() {
|
||||
return opencascade_geometry_ifc_writer_plugin_metadata(STRINGIFY(IfcSchema));
|
||||
}
|
||||
|
||||
void register_plugin(opencascade_geometry_ifc_writer_registry& registry, const ifcopenshell::plugin::module& module) {
|
||||
registry.bind(STRINGIFY(IfcSchema), &serialise_adapter, &tesselate_adapter, module);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_DLL_ALIAS(IfcGeom::opencascade_geometry_ifc_writer_plugin::plugin_abi, ifcopenshell_plugin_abi_v1)
|
||||
BOOST_DLL_ALIAS(IfcGeom::opencascade_geometry_ifc_writer_plugin::plugin_metadata, ifcopenshell_plugin_metadata_v1)
|
||||
BOOST_DLL_ALIAS(IfcGeom::opencascade_geometry_ifc_writer_plugin::register_plugin, ifcopenshell_register_opencascade_geometry_ifc_writer_plugin_v1)
|
||||
@@ -1,57 +1,29 @@
|
||||
#include "abstract_mapping.h"
|
||||
|
||||
#include "../ifcparse/file.h"
|
||||
#include "../ifcgeom/mapping_plugin.h"
|
||||
|
||||
#include <boost/preprocessor/stringize.hpp>
|
||||
#include <boost/preprocessor/seq/for_each.hpp>
|
||||
#include <boost/algorithm/string/case_conv.hpp>
|
||||
#include <mutex>
|
||||
|
||||
#ifndef SCHEMA_SEQ
|
||||
static_assert(false, "A boost preprocessor sequence of schema identifiers is needed for this file to compile.");
|
||||
#endif
|
||||
|
||||
// Declares the schema-based external kernel initialization routines:
|
||||
// - extern void init_MappingImplementation_Ifc2x3(IfcGeom::impl::mapping_registry*);
|
||||
// - ...
|
||||
#define EXTERNAL_DEFS(r, data, elem) \
|
||||
extern void BOOST_PP_CAT(init_MappingImplementation_Ifc, elem)(ifcopenshell::geometry::impl::mapping_registry*);
|
||||
|
||||
// Declares the schema-based external iterator initialization routines:
|
||||
// - init_MappingImplementation_Ifc2x3(this);
|
||||
// - ...
|
||||
#define CALL_DEFS(r, data, elem) \
|
||||
BOOST_PP_CAT(init_MappingImplementation_Ifc, elem)(®istry);
|
||||
|
||||
BOOST_PP_SEQ_FOR_EACH(EXTERNAL_DEFS, , SCHEMA_SEQ)
|
||||
|
||||
namespace {
|
||||
std::string mapping_key(const std::string& schema_name) {
|
||||
return boost::to_lower_copy(schema_name);
|
||||
}
|
||||
|
||||
ifcopenshell::plugin::module builtin_mapping_module(const std::string& schema_name) {
|
||||
ifcopenshell::plugin::metadata metadata;
|
||||
metadata.kind_ = ifcopenshell::plugin::kind::mapping;
|
||||
metadata.id = "geometry.mapping." + boost::to_lower_copy(schema_name);
|
||||
metadata.schema = schema_name;
|
||||
return ifcopenshell::plugin::module::builtin(metadata);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ifcopenshell::geometry::impl::mapping_registry& ifcopenshell::geometry::impl::mapping_registry_instance() {
|
||||
static mapping_registry registry;
|
||||
static std::once_flag once;
|
||||
std::call_once(once, []() {
|
||||
BOOST_PP_SEQ_FOR_EACH(CALL_DEFS, , SCHEMA_SEQ)
|
||||
});
|
||||
std::call_once(once, load_mapping_plugins, std::ref(registry));
|
||||
return registry;
|
||||
}
|
||||
|
||||
void ifcopenshell::geometry::impl::mapping_registry::bind(const std::string& schema_name, ifcopenshell::geometry::impl::mapping_fn fn, const plugin::module& module) {
|
||||
auto& entry = entries_[mapping_key(schema_name)];
|
||||
entry.fn_ = fn;
|
||||
entry.module_ = module.meta().id.empty() ? builtin_mapping_module(schema_name) : module;
|
||||
entry.module_ = module.meta().id.empty() ? plugin::module(mapping_plugin_metadata(schema_name)) : module;
|
||||
}
|
||||
|
||||
ifcopenshell::geometry::abstract_mapping* ifcopenshell::geometry::impl::mapping_registry::construct(ifcopenshell::file* file, Settings& s) {
|
||||
@@ -75,7 +47,7 @@ ifcopenshell::geometry::impl::MappingFactoryImplementation::MappingFactoryImplem
|
||||
}
|
||||
|
||||
void ifcopenshell::geometry::impl::MappingFactoryImplementation::bind(const std::string& schema_name, ifcopenshell::geometry::impl::mapping_fn fn) {
|
||||
mapping_registry_instance().bind(schema_name, fn, builtin_mapping_module(schema_name));
|
||||
mapping_registry_instance().bind(schema_name, fn, plugin::module(mapping_plugin_metadata(schema_name)));
|
||||
}
|
||||
|
||||
ifcopenshell::geometry::abstract_mapping* ifcopenshell::geometry::impl::MappingFactoryImplementation::construct(ifcopenshell::file* file, Settings& s) {
|
||||
|
||||
@@ -82,13 +82,13 @@ namespace geometry {
|
||||
|
||||
class IFC_GEOM_API mapping_registry {
|
||||
public:
|
||||
void bind(const std::string& schema_name, mapping_fn fn, const plugin::module& module = plugin::module());
|
||||
void bind(const std::string& schema_name, mapping_fn fn, const ifcopenshell::plugin::module& module = ifcopenshell::plugin::module());
|
||||
abstract_mapping* construct(ifcopenshell::file* file, Settings& settings);
|
||||
|
||||
private:
|
||||
struct entry {
|
||||
mapping_fn fn_;
|
||||
plugin::module module_;
|
||||
ifcopenshell::plugin::module module_;
|
||||
};
|
||||
|
||||
std::map<std::string, entry> entries_;
|
||||
|
||||
@@ -20,7 +20,9 @@
|
||||
#ifndef IFC_GEOM_API_H
|
||||
#define IFC_GEOM_API_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef SWIG
|
||||
#define IFC_GEOM_API
|
||||
#elif defined(_WIN32)
|
||||
#ifdef IFC_GEOM_EXPORTS
|
||||
#define IFC_GEOM_API __declspec(dllexport)
|
||||
#else
|
||||
|
||||
@@ -19,12 +19,6 @@
|
||||
|
||||
#include "kernel_plugin.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <dlfcn.h>
|
||||
#else
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
namespace {
|
||||
@@ -43,30 +37,7 @@ ifcopenshell::plugin::metadata ifcopenshell::geometry::kernels::kernel_plugin_me
|
||||
}
|
||||
|
||||
std::filesystem::path ifcopenshell::geometry::kernels::kernel_plugin_directory() {
|
||||
#ifdef _WIN32
|
||||
HMODULE module_handle = nullptr;
|
||||
if (!GetModuleHandleExW(
|
||||
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
|
||||
reinterpret_cast<LPCWSTR>(&ifcopenshell::geometry::kernels::load_kernel_plugins),
|
||||
&module_handle)) {
|
||||
throw std::runtime_error("Unable to resolve IfcGeom module path");
|
||||
}
|
||||
|
||||
wchar_t buffer[MAX_PATH];
|
||||
const DWORD length = GetModuleFileNameW(module_handle, buffer, MAX_PATH);
|
||||
if (length == 0) {
|
||||
throw std::runtime_error("Unable to read IfcGeom module filename");
|
||||
}
|
||||
|
||||
return std::filesystem::path(std::wstring(buffer, length)).parent_path();
|
||||
#else
|
||||
Dl_info info;
|
||||
if (dladdr(reinterpret_cast<const void*>(&ifcopenshell::geometry::kernels::load_kernel_plugins), &info) == 0 || !info.dli_fname) {
|
||||
throw std::runtime_error("Unable to resolve IfcGeom module path");
|
||||
}
|
||||
|
||||
return std::filesystem::path(info.dli_fname).parent_path();
|
||||
#endif
|
||||
return plugin::module_directory(reinterpret_cast<const void*>(&ifcopenshell::geometry::kernels::load_kernel_plugins));
|
||||
}
|
||||
|
||||
void ifcopenshell::geometry::kernels::load_kernel_plugins(kernel_registry& registry) {
|
||||
|
||||
@@ -28,10 +28,10 @@ namespace ifcopenshell {
|
||||
namespace geometry {
|
||||
namespace kernels {
|
||||
|
||||
typedef void register_kernel_plugin_fn(kernel_registry&, const plugin::module&);
|
||||
typedef void register_kernel_plugin_fn(kernel_registry&, const ifcopenshell::plugin::module&);
|
||||
|
||||
IFC_GEOM_API const char* kernel_plugin_registration_symbol();
|
||||
IFC_GEOM_API plugin::metadata kernel_plugin_metadata(const std::string& plugin_name);
|
||||
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);
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace ifcopenshell {
|
||||
public:
|
||||
typedef boost::function2<AbstractKernel*, ifcopenshell::file*, Settings&> create_fn;
|
||||
|
||||
void bind(const kernel_info& info, create_fn create, const plugin::module& module = plugin::module());
|
||||
void bind(const kernel_info& info, create_fn create, const ifcopenshell::plugin::module& module = ifcopenshell::plugin::module());
|
||||
bool has(const std::string& backend_id) const;
|
||||
std::unique_ptr<AbstractKernel> create(const std::string& backend_id, ifcopenshell::file* file, Settings& settings) const;
|
||||
std::vector<kernel_info> kernels() const;
|
||||
@@ -54,7 +54,7 @@ namespace ifcopenshell {
|
||||
struct entry {
|
||||
kernel_info info_;
|
||||
create_fn create_;
|
||||
plugin::module module_;
|
||||
ifcopenshell::plugin::module module_;
|
||||
};
|
||||
|
||||
std::map<std::string, entry> entries_;
|
||||
|
||||
@@ -6,6 +6,12 @@ foreach(kernel ${GEOMETRY_KERNELS})
|
||||
string(TOUPPER ${kernel} KERNEL_UPPER)
|
||||
file(GLOB IFCGEOM_H_FILES ${kernel}/*.h)
|
||||
file(GLOB IFCGEOM_CPP_FILES ${kernel}/*.cpp)
|
||||
if(${kernel} STREQUAL "opencascade")
|
||||
list(REMOVE_ITEM IFCGEOM_CPP_FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/${kernel}/tree_brep_plugin.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/${kernel}/tree_trianglebvh_plugin.cpp
|
||||
)
|
||||
endif()
|
||||
set(IFCGEOM_FILES ${IFCGEOM_CPP_FILES} ${IFCGEOM_H_FILES})
|
||||
|
||||
set(KERNEL_TARGET "geometry_kernel_${kernel}")
|
||||
@@ -37,6 +43,23 @@ foreach(kernel ${GEOMETRY_KERNELS})
|
||||
install(TARGETS ${KERNEL_TARGET_SIMPLE})
|
||||
elseif(${kernel} STREQUAL "opencascade")
|
||||
target_link_libraries(${KERNEL_TARGET} PRIVATE ${OpenCASCADE_LIBRARIES})
|
||||
|
||||
foreach(tree_backend brep trianglebvh)
|
||||
set(TREE_TARGET "geometry_tree_opencascade_${tree_backend}")
|
||||
add_library(${TREE_TARGET} SHARED
|
||||
${kernel}/tree_${tree_backend}_plugin.cpp
|
||||
${kernel}/tree_backends.h
|
||||
)
|
||||
set_target_properties(${TREE_TARGET} PROPERTIES
|
||||
COMPILE_FLAGS "-DIFC_GEOMLIBRARY_EXPORTS"
|
||||
OUTPUT_NAME "geometry.tree.opencascade.${tree_backend}"
|
||||
RUNTIME_OUTPUT_DIRECTORY "${kernel_plugin_runtime_dir}"
|
||||
LIBRARY_OUTPUT_DIRECTORY "${kernel_plugin_runtime_dir}"
|
||||
)
|
||||
list(APPEND tree_libraries ${TREE_TARGET})
|
||||
target_link_libraries(${TREE_TARGET} PRIVATE plugin IfcGeom geometry_kernel_opencascade ${OpenCASCADE_LIBRARIES} Eigen3::Eigen)
|
||||
install(TARGETS ${TREE_TARGET})
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
install(FILES ${IFCGEOM_H_FILES}
|
||||
@@ -45,3 +68,4 @@ foreach(kernel ${GEOMETRY_KERNELS})
|
||||
endforeach()
|
||||
|
||||
set(kernel_libraries ${kernel_libraries} PARENT_SCOPE)
|
||||
set(tree_libraries ${tree_libraries} PARENT_SCOPE)
|
||||
|
||||
@@ -20,7 +20,9 @@
|
||||
#ifndef IFC_GEOMLIBRARY_API_H
|
||||
#define IFC_GEOMLIBRARY_API_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef SWIG
|
||||
#define IFC_GEOMLIBRARY_API
|
||||
#elif defined(_WIN32)
|
||||
#ifdef IFC_GEOMLIBRARY_EXPORTS
|
||||
#define IFC_GEOMLIBRARY_API __declspec(dllexport)
|
||||
#else
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include "../../../ifcgeom/IfcGeomElement.h"
|
||||
#include "../../../ifcgeom/Iterator.h"
|
||||
#include "../../../ifcgeom/tree.h"
|
||||
#include "OpenCascadeConversionResult.h"
|
||||
#include "OpenCascadeKernel.h"
|
||||
#include "base_utils.h"
|
||||
@@ -69,26 +70,6 @@
|
||||
|
||||
|
||||
namespace IfcGeom {
|
||||
|
||||
struct ray_intersection_result {
|
||||
double distance;
|
||||
int style_index;
|
||||
express::Entity instance;
|
||||
std::array<double, 3> position;
|
||||
std::array<double, 3> normal;
|
||||
double ray_distance;
|
||||
double dot_product;
|
||||
};
|
||||
|
||||
struct clash {
|
||||
int clash_type; // 0 = protrusion, 1 = pierce, 2 = collision, 3 = clearance
|
||||
express::Base a;
|
||||
express::Base b;
|
||||
double distance;
|
||||
std::array<double, 3> p1;
|
||||
std::array<double, 3> p2;
|
||||
};
|
||||
|
||||
namespace {
|
||||
|
||||
// Approximates the distance `other` protrudes into `volume` by finding the
|
||||
@@ -1481,20 +1462,20 @@ namespace IfcGeom {
|
||||
};
|
||||
}
|
||||
|
||||
class tree : public impl::tree<express::Entity> {
|
||||
class opencascade_tree : public impl::tree<express::Entity> {
|
||||
public:
|
||||
|
||||
tree() {};
|
||||
opencascade_tree() {};
|
||||
|
||||
tree(ifcopenshell::file& f) {
|
||||
opencascade_tree(ifcopenshell::file& f) {
|
||||
add_file(f, ifcopenshell::geometry::Settings{});
|
||||
}
|
||||
|
||||
tree(ifcopenshell::file& f, ifcopenshell::geometry::Settings settings) {
|
||||
opencascade_tree(ifcopenshell::file& f, ifcopenshell::geometry::Settings settings) {
|
||||
add_file(f, settings);
|
||||
}
|
||||
|
||||
tree(IfcGeom::Iterator& it) {
|
||||
opencascade_tree(IfcGeom::Iterator& it) {
|
||||
add_file(it);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,182 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef IFCOPENSHELL_OPENCASCADE_TREE_BACKENDS_H
|
||||
#define IFCOPENSHELL_OPENCASCADE_TREE_BACKENDS_H
|
||||
|
||||
#include "../../kernel_registry.h"
|
||||
#include "../../tree_registry.h"
|
||||
#include "../../../ifcparse/exception.h"
|
||||
#include "IfcGeomTree.h"
|
||||
|
||||
namespace ifcopenshell {
|
||||
namespace geometry {
|
||||
namespace trees {
|
||||
namespace opencascade_tree_backends {
|
||||
|
||||
inline gp_Pnt make_point(const IfcGeom::tree_point& point) {
|
||||
return gp_Pnt(point[0], point[1], point[2]);
|
||||
}
|
||||
|
||||
inline Bnd_Box make_box(const IfcGeom::tree_box& bounds) {
|
||||
Bnd_Box box;
|
||||
box.Add(make_point(bounds[0]));
|
||||
box.Add(make_point(bounds[1]));
|
||||
return box;
|
||||
}
|
||||
|
||||
class brep_tree : public abstract_tree {
|
||||
public:
|
||||
std::string_view backend_id() const override {
|
||||
return "opencascade.brep";
|
||||
}
|
||||
|
||||
void add_file(ifcopenshell::file& file, const ifcopenshell::geometry::Settings& settings) override {
|
||||
auto settings_ = settings;
|
||||
settings_.get<ifcopenshell::geometry::settings::IteratorOutput>().value = ifcopenshell::geometry::settings::NATIVE;
|
||||
settings_.get<ifcopenshell::geometry::settings::UseWorldCoords>().value = true;
|
||||
settings_.get<ifcopenshell::geometry::settings::ReorientShells>().value = true;
|
||||
|
||||
IfcGeom::Iterator iterator(ifcopenshell::geometry::kernels::construct(&file, "opencascade", settings_), settings_, &file, {}, 1);
|
||||
if (iterator.initialize()) {
|
||||
do {
|
||||
add_element(iterator.get());
|
||||
} while (iterator.next());
|
||||
}
|
||||
}
|
||||
|
||||
void add_element(IfcGeom::Element* element) override {
|
||||
auto* brep = dynamic_cast<IfcGeom::BRepElement*>(element);
|
||||
if (!brep) {
|
||||
throw ifcopenshell::exception("Tree backend 'opencascade.brep' requires native BRep elements");
|
||||
}
|
||||
tree_.add_element(brep);
|
||||
}
|
||||
|
||||
std::vector<express::Entity> select_box(const express::Entity& entity, bool completely_within, double extend) const override {
|
||||
return tree_.select_box(entity, completely_within, extend);
|
||||
}
|
||||
|
||||
std::vector<express::Entity> select_box(const IfcGeom::tree_point& point) const override {
|
||||
return tree_.select_box(make_point(point));
|
||||
}
|
||||
|
||||
std::vector<express::Entity> select_box(const IfcGeom::tree_box& bounds, bool completely_within) const override {
|
||||
return tree_.select_box(make_box(bounds), completely_within);
|
||||
}
|
||||
|
||||
std::vector<express::Entity> select(const express::Entity& entity, bool completely_within, double extend) const override {
|
||||
return tree_.select(entity, completely_within, extend);
|
||||
}
|
||||
|
||||
std::vector<express::Entity> select(const IfcGeom::Element* element, bool completely_within, double extend) const override {
|
||||
auto* brep = dynamic_cast<const IfcGeom::BRepElement*>(element);
|
||||
if (!brep) {
|
||||
throw ifcopenshell::exception("Tree backend 'opencascade.brep' requires BRep elements for select()");
|
||||
}
|
||||
return tree_.select(brep, completely_within, extend);
|
||||
}
|
||||
|
||||
std::vector<express::Entity> select(const IfcGeom::tree_point& point, double extend) const override {
|
||||
return tree_.select(make_point(point), extend);
|
||||
}
|
||||
|
||||
std::vector<IfcGeom::ray_intersection_result> select_ray(const IfcGeom::tree_point& origin, const IfcGeom::tree_point& direction, double length) const override {
|
||||
return tree_.select_ray(make_point(origin), gp_Dir(direction[0], direction[1], direction[2]), length);
|
||||
}
|
||||
|
||||
const std::vector<double>& distances() const override {
|
||||
return tree_.distances();
|
||||
}
|
||||
|
||||
const std::vector<double>& protrusion_distances() const override {
|
||||
return tree_.protrusion_distances();
|
||||
}
|
||||
|
||||
bool enable_face_styles() const override {
|
||||
return tree_.enable_face_styles();
|
||||
}
|
||||
|
||||
void enable_face_styles(bool enable) override {
|
||||
tree_.enable_face_styles(enable);
|
||||
}
|
||||
|
||||
const std::vector<ifcopenshell::geometry::taxonomy::style::ptr>& styles() const override {
|
||||
return tree_.styles();
|
||||
}
|
||||
|
||||
private:
|
||||
IfcGeom::opencascade_tree tree_;
|
||||
};
|
||||
|
||||
class trianglebvh_tree : public abstract_tree {
|
||||
public:
|
||||
std::string_view backend_id() const override {
|
||||
return "opencascade.trianglebvh";
|
||||
}
|
||||
|
||||
void add_file(ifcopenshell::file& file, const ifcopenshell::geometry::Settings& settings) override {
|
||||
auto settings_ = settings;
|
||||
settings_.get<ifcopenshell::geometry::settings::IteratorOutput>().value = ifcopenshell::geometry::settings::TRIANGULATED;
|
||||
settings_.get<ifcopenshell::geometry::settings::UseWorldCoords>().value = true;
|
||||
|
||||
IfcGeom::Iterator iterator(ifcopenshell::geometry::kernels::construct(&file, "opencascade", settings_), settings_, &file, {}, 1);
|
||||
if (iterator.initialize()) {
|
||||
do {
|
||||
add_element(iterator.get());
|
||||
} while (iterator.next());
|
||||
}
|
||||
}
|
||||
|
||||
void add_element(IfcGeom::Element* element) override {
|
||||
auto* triangulation = dynamic_cast<IfcGeom::TriangulationElement*>(element);
|
||||
if (!triangulation) {
|
||||
throw ifcopenshell::exception("Tree backend 'opencascade.trianglebvh' requires triangulation elements");
|
||||
}
|
||||
tree_.add_element(triangulation);
|
||||
}
|
||||
|
||||
std::vector<IfcGeom::clash> clash_intersection_many(const std::vector<express::Entity>& set_a, const std::vector<express::Entity>& set_b, double tolerance, bool check_all) const override {
|
||||
return tree_.clash_intersection_many(set_a, set_b, tolerance, check_all);
|
||||
}
|
||||
|
||||
std::vector<IfcGeom::clash> clash_collision_many(const std::vector<express::Entity>& set_a, const std::vector<express::Entity>& set_b, bool allow_touching) const override {
|
||||
return tree_.clash_collision_many(set_a, set_b, allow_touching);
|
||||
}
|
||||
|
||||
std::vector<IfcGeom::clash> clash_clearance_many(const std::vector<express::Entity>& set_a, const std::vector<express::Entity>& set_b, double clearance, bool check_all) const override {
|
||||
return tree_.clash_clearance_many(set_a, set_b, clearance, check_all);
|
||||
}
|
||||
|
||||
#ifdef WITH_HDF5
|
||||
void write_h5() override {
|
||||
tree_.write_h5();
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
IfcGeom::opencascade_tree tree_;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,55 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#include "../../tree_plugin.h"
|
||||
#include "tree_backends.h"
|
||||
|
||||
#include <boost/dll/alias.hpp>
|
||||
|
||||
namespace ifcopenshell {
|
||||
namespace geometry {
|
||||
namespace trees {
|
||||
namespace opencascade_brep_tree_plugin {
|
||||
|
||||
plugin::abi_info plugin_abi() {
|
||||
return plugin::host_abi();
|
||||
}
|
||||
|
||||
plugin::metadata plugin_metadata() {
|
||||
return tree_plugin_metadata("opencascade.brep");
|
||||
}
|
||||
|
||||
abstract_tree* create_tree() {
|
||||
return new opencascade_tree_backends::brep_tree();
|
||||
}
|
||||
|
||||
void register_plugin(tree_registry& registry, const plugin::module& module) {
|
||||
tree_info info;
|
||||
info.backend_id = "opencascade.brep";
|
||||
registry.bind(info, create_tree, module);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_DLL_ALIAS(ifcopenshell::geometry::trees::opencascade_brep_tree_plugin::plugin_abi, ifcopenshell_plugin_abi_v1)
|
||||
BOOST_DLL_ALIAS(ifcopenshell::geometry::trees::opencascade_brep_tree_plugin::plugin_metadata, ifcopenshell_plugin_metadata_v1)
|
||||
BOOST_DLL_ALIAS(ifcopenshell::geometry::trees::opencascade_brep_tree_plugin::register_plugin, ifcopenshell_register_tree_plugin_v1)
|
||||
@@ -0,0 +1,55 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#include "../../tree_plugin.h"
|
||||
#include "tree_backends.h"
|
||||
|
||||
#include <boost/dll/alias.hpp>
|
||||
|
||||
namespace ifcopenshell {
|
||||
namespace geometry {
|
||||
namespace trees {
|
||||
namespace opencascade_trianglebvh_tree_plugin {
|
||||
|
||||
plugin::abi_info plugin_abi() {
|
||||
return plugin::host_abi();
|
||||
}
|
||||
|
||||
plugin::metadata plugin_metadata() {
|
||||
return tree_plugin_metadata("opencascade.trianglebvh");
|
||||
}
|
||||
|
||||
abstract_tree* create_tree() {
|
||||
return new opencascade_tree_backends::trianglebvh_tree();
|
||||
}
|
||||
|
||||
void register_plugin(tree_registry& registry, const plugin::module& module) {
|
||||
tree_info info;
|
||||
info.backend_id = "opencascade.trianglebvh";
|
||||
registry.bind(info, create_tree, module);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_DLL_ALIAS(ifcopenshell::geometry::trees::opencascade_trianglebvh_tree_plugin::plugin_abi, ifcopenshell_plugin_abi_v1)
|
||||
BOOST_DLL_ALIAS(ifcopenshell::geometry::trees::opencascade_trianglebvh_tree_plugin::plugin_metadata, ifcopenshell_plugin_metadata_v1)
|
||||
BOOST_DLL_ALIAS(ifcopenshell::geometry::trees::opencascade_trianglebvh_tree_plugin::register_plugin, ifcopenshell_register_tree_plugin_v1)
|
||||
@@ -1,14 +1,21 @@
|
||||
find_package(Eigen3 REQUIRED)
|
||||
|
||||
set(mapping_plugin_runtime_dir "${CMAKE_BINARY_DIR}/ifcgeom/$<CONFIG>")
|
||||
|
||||
foreach(schema ${SCHEMA_VERSIONS})
|
||||
file(GLOB IFCGEOM_I_FILES *.i)
|
||||
file(GLOB IFCGEOM_H_FILES *.h)
|
||||
file(GLOB IFCGEOM_CPP_FILES *.cpp)
|
||||
set(IFCGEOM_FILES ${IFCGEOM_CPP_FILES} ${IFCGEOM_H_FILES} ${IFCGEOM_I_FILES})
|
||||
|
||||
add_library(geometry_mapping_ifc${schema} OBJECT ${IFCGEOM_FILES})
|
||||
set_target_properties(geometry_mapping_ifc${schema} PROPERTIES COMPILE_FLAGS "-DIFC_GEOM_EXPORTS -DIfcSchema=Ifc${schema}")
|
||||
target_link_libraries(geometry_mapping_ifc${schema} IfcParse Eigen3::Eigen)
|
||||
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}"
|
||||
RUNTIME_OUTPUT_DIRECTORY "${mapping_plugin_runtime_dir}"
|
||||
LIBRARY_OUTPUT_DIRECTORY "${mapping_plugin_runtime_dir}"
|
||||
)
|
||||
target_link_libraries(geometry_mapping_ifc${schema} PRIVATE plugin IfcGeom IfcParse Eigen3::Eigen ${OpenCASCADE_LIBRARIES})
|
||||
|
||||
list(APPEND mapping_libraries geometry_mapping_ifc${schema})
|
||||
|
||||
|
||||
@@ -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/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#include "../mapping_plugin.h"
|
||||
#include "mapping.h"
|
||||
|
||||
#include <boost/dll/alias.hpp>
|
||||
|
||||
namespace ifcopenshell {
|
||||
namespace geometry {
|
||||
namespace impl {
|
||||
namespace mapping_plugin {
|
||||
|
||||
namespace {
|
||||
struct POSTFIX_SCHEMA(factory_t) {
|
||||
abstract_mapping* operator()(ifcopenshell::file* file, Settings& settings) const {
|
||||
return new POSTFIX_SCHEMA(mapping)(file, settings);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
plugin::abi_info plugin_abi() {
|
||||
return plugin::host_abi();
|
||||
}
|
||||
|
||||
plugin::metadata plugin_metadata() {
|
||||
return mapping_plugin_metadata(STRINGIFY(IfcSchema));
|
||||
}
|
||||
|
||||
void register_plugin(mapping_registry& registry, const plugin::module& module) {
|
||||
POSTFIX_SCHEMA(factory_t) factory;
|
||||
registry.bind(STRINGIFY(IfcSchema), factory, module);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_DLL_ALIAS(ifcopenshell::geometry::impl::mapping_plugin::plugin_abi, ifcopenshell_plugin_abi_v1)
|
||||
BOOST_DLL_ALIAS(ifcopenshell::geometry::impl::mapping_plugin::plugin_metadata, ifcopenshell_plugin_metadata_v1)
|
||||
BOOST_DLL_ALIAS(ifcopenshell::geometry::impl::mapping_plugin::register_plugin, ifcopenshell_register_mapping_plugin_v1)
|
||||
@@ -0,0 +1,57 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#include "mapping_plugin.h"
|
||||
|
||||
#include <boost/algorithm/string/case_conv.hpp>
|
||||
|
||||
namespace {
|
||||
constexpr const char* mapping_plugin_prefix = "geometry.mapping.";
|
||||
}
|
||||
|
||||
const char* ifcopenshell::geometry::impl::mapping_plugin_registration_symbol() {
|
||||
return "ifcopenshell_register_mapping_plugin_v1";
|
||||
}
|
||||
|
||||
ifcopenshell::plugin::metadata ifcopenshell::geometry::impl::mapping_plugin_metadata(const std::string& schema_name) {
|
||||
plugin::metadata metadata;
|
||||
metadata.kind_ = plugin::kind::mapping;
|
||||
metadata.id = mapping_plugin_prefix + boost::to_lower_copy(schema_name);
|
||||
metadata.schema = boost::to_upper_copy(schema_name);
|
||||
return metadata;
|
||||
}
|
||||
|
||||
std::filesystem::path ifcopenshell::geometry::impl::mapping_plugin_directory() {
|
||||
return plugin::module_directory(reinterpret_cast<const void*>(&ifcopenshell::geometry::impl::load_mapping_plugins));
|
||||
}
|
||||
|
||||
void ifcopenshell::geometry::impl::load_mapping_plugins(mapping_registry& registry) {
|
||||
plugin::manager manager;
|
||||
manager.add_search_path(mapping_plugin_directory());
|
||||
|
||||
for (const auto& path : manager.discover(mapping_plugin_prefix)) {
|
||||
auto module = manager.load(path);
|
||||
if (module.meta().kind_ != plugin::kind::mapping) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto register_plugin = module.get_alias<register_mapping_plugin_fn>(mapping_plugin_registration_symbol());
|
||||
register_plugin(registry, module);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef IFCOPENSHELL_MAPPING_PLUGIN_H
|
||||
#define IFCOPENSHELL_MAPPING_PLUGIN_H
|
||||
|
||||
#include "../ifcgeom/abstract_mapping.h"
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
namespace ifcopenshell {
|
||||
namespace geometry {
|
||||
namespace impl {
|
||||
|
||||
typedef void register_mapping_plugin_fn(mapping_registry&, const ifcopenshell::plugin::module&);
|
||||
|
||||
IFC_GEOM_API const char* mapping_plugin_registration_symbol();
|
||||
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);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef PROFILE_HELPER_H
|
||||
#define PROFILE_HELPER_H
|
||||
|
||||
#include "ifc_geom_api.h"
|
||||
#include "taxonomy.h"
|
||||
|
||||
namespace ifcopenshell {
|
||||
@@ -27,17 +28,17 @@ namespace ifcopenshell {
|
||||
taxonomy::edge::ptr previous, next;
|
||||
};
|
||||
|
||||
taxonomy::loop::ptr polygon_from_points(const std::vector<taxonomy::point3::ptr>& ps, bool external = true);
|
||||
IFC_GEOM_API taxonomy::loop::ptr polygon_from_points(const std::vector<taxonomy::point3::ptr>& ps, bool external = true);
|
||||
|
||||
taxonomy::loop::ptr profile_helper(const taxonomy::matrix4::ptr& m4, const std::vector<profile_point>& points);
|
||||
IFC_GEOM_API taxonomy::loop::ptr profile_helper(const taxonomy::matrix4::ptr& m4, const std::vector<profile_point>& points);
|
||||
|
||||
taxonomy::loop::ptr fillet_loop(taxonomy::loop::ptr lp, double radius);
|
||||
IFC_GEOM_API taxonomy::loop::ptr fillet_loop(taxonomy::loop::ptr lp, double radius);
|
||||
|
||||
void remove_duplicate_points_from_loop(std::vector<taxonomy::point3::ptr>& polygon, bool closed, double tol);
|
||||
IFC_GEOM_API void remove_duplicate_points_from_loop(std::vector<taxonomy::point3::ptr>& polygon, bool closed, double tol);
|
||||
|
||||
std::pair<std::vector<taxonomy::point3::ptr>, std::vector<std::set<std::string>>> remove_duplicate_points_from_loop(const std::vector<taxonomy::point3::ptr>& polygon, const std::vector<std::string>& tags);
|
||||
IFC_GEOM_API std::pair<std::vector<taxonomy::point3::ptr>, std::vector<std::set<std::string>>> remove_duplicate_points_from_loop(const std::vector<taxonomy::point3::ptr>& polygon, const std::vector<std::string>& tags);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,266 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#include "tree.h"
|
||||
|
||||
#include "Iterator.h"
|
||||
#include "tree_registry.h"
|
||||
#include "../ifcparse/exception.h"
|
||||
|
||||
#include <boost/functional/hash.hpp>
|
||||
|
||||
#include <cstdio>
|
||||
#include <limits>
|
||||
#include <unordered_set>
|
||||
|
||||
namespace {
|
||||
constexpr const char* default_selection_backend_id = "opencascade.brep";
|
||||
constexpr const char* default_clash_backend_id = "opencascade.trianglebvh";
|
||||
|
||||
const std::vector<double>& empty_double_vector() {
|
||||
static const std::vector<double> values;
|
||||
return values;
|
||||
}
|
||||
|
||||
const std::vector<ifcopenshell::geometry::taxonomy::style::ptr>& empty_style_vector() {
|
||||
static const std::vector<ifcopenshell::geometry::taxonomy::style::ptr> values;
|
||||
return values;
|
||||
}
|
||||
|
||||
std::vector<express::Entity> to_product_entities(const std::vector<express::Base>& instances) {
|
||||
std::vector<express::Entity> entities;
|
||||
entities.reserve(instances.size());
|
||||
|
||||
for (const auto& instance : instances) {
|
||||
if (!instance) {
|
||||
throw ifcopenshell::exception("All instances should be of type IfcProduct");
|
||||
}
|
||||
|
||||
auto entity = instance.as<express::Entity>();
|
||||
if (!entity || !instance.declaration().is("IfcProduct")) {
|
||||
throw ifcopenshell::exception("All instances should be of type IfcProduct");
|
||||
}
|
||||
entities.push_back(entity);
|
||||
}
|
||||
|
||||
return entities;
|
||||
}
|
||||
}
|
||||
|
||||
class IfcGeom::tree::impl {
|
||||
public:
|
||||
impl() = default;
|
||||
|
||||
explicit impl(const std::string& backend_id)
|
||||
: backend_id_(backend_id)
|
||||
{}
|
||||
|
||||
ifcopenshell::geometry::trees::abstract_tree& backend() const {
|
||||
if (!backend_) {
|
||||
if (backend_id_.empty()) {
|
||||
throw ifcopenshell::exception("No geometry tree backend configured");
|
||||
}
|
||||
backend_ = ifcopenshell::geometry::trees::construct(backend_id_);
|
||||
}
|
||||
return *backend_;
|
||||
}
|
||||
|
||||
ifcopenshell::geometry::trees::abstract_tree& backend(const std::string& default_backend_id) const {
|
||||
if (backend_id_.empty()) {
|
||||
backend_id_ = default_backend_id;
|
||||
}
|
||||
return backend();
|
||||
}
|
||||
|
||||
ifcopenshell::geometry::trees::abstract_tree& backend_for_element(IfcGeom::Element* element) const {
|
||||
if (dynamic_cast<IfcGeom::BRepElement*>(element)) {
|
||||
return backend(default_selection_backend_id);
|
||||
}
|
||||
|
||||
if (dynamic_cast<IfcGeom::TriangulationElement*>(element)) {
|
||||
return backend(default_clash_backend_id);
|
||||
}
|
||||
|
||||
throw ifcopenshell::exception("Unsupported tree element type");
|
||||
}
|
||||
|
||||
const ifcopenshell::geometry::trees::abstract_tree* backend_or_null() const {
|
||||
return backend_.get();
|
||||
}
|
||||
|
||||
private:
|
||||
mutable std::string backend_id_;
|
||||
mutable std::unique_ptr<ifcopenshell::geometry::trees::abstract_tree> backend_;
|
||||
};
|
||||
|
||||
IfcGeom::tree::tree()
|
||||
: impl_(new impl())
|
||||
{}
|
||||
|
||||
IfcGeom::tree::tree(const std::string& backend_id)
|
||||
: impl_(new impl(backend_id))
|
||||
{}
|
||||
|
||||
IfcGeom::tree::tree(ifcopenshell::file& file)
|
||||
: tree()
|
||||
{
|
||||
add_file(file, ifcopenshell::geometry::Settings{});
|
||||
}
|
||||
|
||||
IfcGeom::tree::tree(ifcopenshell::file& file, const ifcopenshell::geometry::Settings& settings)
|
||||
: tree()
|
||||
{
|
||||
add_file(file, settings);
|
||||
}
|
||||
|
||||
IfcGeom::tree::tree(IfcGeom::Iterator& iterator)
|
||||
: tree()
|
||||
{
|
||||
add_file(iterator);
|
||||
}
|
||||
|
||||
IfcGeom::tree::~tree() = default;
|
||||
|
||||
IfcGeom::tree::tree(tree&& other) noexcept = default;
|
||||
|
||||
IfcGeom::tree& IfcGeom::tree::operator=(tree&& other) noexcept = default;
|
||||
|
||||
void IfcGeom::tree::add_file(ifcopenshell::file& file, const ifcopenshell::geometry::Settings& settings) {
|
||||
impl_->backend(default_selection_backend_id).add_file(file, settings);
|
||||
}
|
||||
|
||||
void IfcGeom::tree::add_file(IfcGeom::Iterator& iterator) {
|
||||
if (!iterator.initialize()) {
|
||||
return;
|
||||
}
|
||||
|
||||
do {
|
||||
add_element(iterator.get());
|
||||
} while (iterator.next());
|
||||
}
|
||||
|
||||
void IfcGeom::tree::add_element(IfcGeom::Element* element) {
|
||||
if (!element) {
|
||||
return;
|
||||
}
|
||||
|
||||
impl_->backend_for_element(element).add_element(element);
|
||||
}
|
||||
|
||||
std::vector<express::Entity> IfcGeom::tree::select_box(const express::Entity& entity, bool completely_within, double extend) const {
|
||||
return impl_->backend(default_selection_backend_id).select_box(entity, completely_within, extend);
|
||||
}
|
||||
|
||||
std::vector<express::Entity> IfcGeom::tree::select_box(const tree_point& point) const {
|
||||
return impl_->backend(default_selection_backend_id).select_box(point);
|
||||
}
|
||||
|
||||
std::vector<express::Entity> IfcGeom::tree::select_box(const tree_box& bounds, bool completely_within) const {
|
||||
return impl_->backend(default_selection_backend_id).select_box(bounds, completely_within);
|
||||
}
|
||||
|
||||
std::vector<express::Entity> IfcGeom::tree::select(const express::Entity& entity, bool completely_within, double extend) const {
|
||||
return impl_->backend(default_selection_backend_id).select(entity, completely_within, extend);
|
||||
}
|
||||
|
||||
std::vector<express::Entity> IfcGeom::tree::select(const IfcGeom::Element* element, bool completely_within, double extend) const {
|
||||
return impl_->backend(default_selection_backend_id).select(element, completely_within, extend);
|
||||
}
|
||||
|
||||
std::vector<express::Entity> IfcGeom::tree::select(const tree_point& point, double extend) const {
|
||||
return impl_->backend(default_selection_backend_id).select(point, extend);
|
||||
}
|
||||
|
||||
std::vector<IfcGeom::ray_intersection_result> IfcGeom::tree::select_ray(const tree_point& origin, const tree_point& direction, double length) const {
|
||||
return impl_->backend(default_selection_backend_id).select_ray(origin, direction, length);
|
||||
}
|
||||
|
||||
std::vector<IfcGeom::clash> IfcGeom::tree::clash_intersection_many(const std::vector<express::Base>& set_a, const std::vector<express::Base>& set_b, double tolerance, bool check_all) const {
|
||||
return impl_->backend(default_clash_backend_id).clash_intersection_many(to_product_entities(set_a), to_product_entities(set_b), tolerance, check_all);
|
||||
}
|
||||
|
||||
std::vector<IfcGeom::clash> IfcGeom::tree::clash_collision_many(const std::vector<express::Base>& set_a, const std::vector<express::Base>& set_b, bool allow_touching) const {
|
||||
return impl_->backend(default_clash_backend_id).clash_collision_many(to_product_entities(set_a), to_product_entities(set_b), allow_touching);
|
||||
}
|
||||
|
||||
std::vector<IfcGeom::clash> IfcGeom::tree::clash_clearance_many(const std::vector<express::Base>& set_a, const std::vector<express::Base>& set_b, double clearance, bool check_all) const {
|
||||
return impl_->backend(default_clash_backend_id).clash_clearance_many(to_product_entities(set_a), to_product_entities(set_b), clearance, check_all);
|
||||
}
|
||||
|
||||
const std::vector<double>& IfcGeom::tree::distances() const {
|
||||
const auto* backend = impl_->backend_or_null();
|
||||
return backend ? backend->distances() : empty_double_vector();
|
||||
}
|
||||
|
||||
const std::vector<double>& IfcGeom::tree::protrusion_distances() const {
|
||||
const auto* backend = impl_->backend_or_null();
|
||||
return backend ? backend->protrusion_distances() : empty_double_vector();
|
||||
}
|
||||
|
||||
bool IfcGeom::tree::enable_face_styles() const {
|
||||
const auto* backend = impl_->backend_or_null();
|
||||
return backend ? backend->enable_face_styles() : false;
|
||||
}
|
||||
|
||||
void IfcGeom::tree::enable_face_styles(bool enable) {
|
||||
impl_->backend(default_selection_backend_id).enable_face_styles(enable);
|
||||
}
|
||||
|
||||
const std::vector<ifcopenshell::geometry::taxonomy::style::ptr>& IfcGeom::tree::styles() const {
|
||||
const auto* backend = impl_->backend_or_null();
|
||||
return backend ? backend->styles() : empty_style_vector();
|
||||
}
|
||||
|
||||
#ifdef WITH_HDF5
|
||||
void IfcGeom::tree::write_h5() {
|
||||
impl_->backend(default_clash_backend_id).write_h5();
|
||||
}
|
||||
#endif
|
||||
|
||||
std::string IfcGeom::tree::uint8_to_b64(const std::vector<uint8_t>& uuids_array) const {
|
||||
std::string hex_str;
|
||||
hex_str.reserve(uuids_array.size() * 2);
|
||||
|
||||
for (auto byte : uuids_array) {
|
||||
char hex[3];
|
||||
std::snprintf(hex, sizeof(hex), "%02x", byte);
|
||||
hex_str.append(hex);
|
||||
}
|
||||
|
||||
return hex_str;
|
||||
}
|
||||
|
||||
bool IfcGeom::tree::is_manifold(const std::vector<int>& faces) {
|
||||
std::unordered_set<std::pair<size_t, size_t>, boost::hash<std::pair<size_t, size_t>>> directed_edges;
|
||||
|
||||
for (size_t i = 0; i < faces.size(); i += 3) {
|
||||
for (size_t j = 0; j < 3; ++j) {
|
||||
const auto k = (j + 1) % 3;
|
||||
const std::pair<size_t, size_t> edge(faces[i + j], faces[i + k]);
|
||||
const auto it = directed_edges.find(edge);
|
||||
if (it != directed_edges.end()) {
|
||||
directed_edges.erase(it);
|
||||
} else {
|
||||
directed_edges.insert({ faces[i + k], faces[i + j] });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return directed_edges.empty();
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef IFCOPENSHELL_TREE_H
|
||||
#define IFCOPENSHELL_TREE_H
|
||||
|
||||
#include "IfcGeomElement.h"
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace ifcopenshell {
|
||||
class file;
|
||||
|
||||
namespace geometry {
|
||||
class Settings;
|
||||
}
|
||||
}
|
||||
|
||||
namespace IfcGeom {
|
||||
class Iterator;
|
||||
|
||||
using tree_point = std::array<double, 3>;
|
||||
using tree_box = std::array<tree_point, 2>;
|
||||
|
||||
struct IFC_GEOM_API ray_intersection_result {
|
||||
double distance;
|
||||
int style_index;
|
||||
express::Entity instance;
|
||||
tree_point position;
|
||||
tree_point normal;
|
||||
double ray_distance;
|
||||
double dot_product;
|
||||
};
|
||||
|
||||
struct IFC_GEOM_API clash {
|
||||
int clash_type;
|
||||
express::Base a;
|
||||
express::Base b;
|
||||
double distance;
|
||||
tree_point p1;
|
||||
tree_point p2;
|
||||
};
|
||||
|
||||
class IFC_GEOM_API tree {
|
||||
public:
|
||||
tree();
|
||||
explicit tree(const std::string& backend_id);
|
||||
explicit tree(ifcopenshell::file& file);
|
||||
tree(ifcopenshell::file& file, const ifcopenshell::geometry::Settings& settings);
|
||||
explicit tree(IfcGeom::Iterator& iterator);
|
||||
~tree();
|
||||
|
||||
tree(tree&& other) noexcept;
|
||||
tree& operator=(tree&& other) noexcept;
|
||||
|
||||
tree(const tree& other) = delete;
|
||||
tree& operator=(const tree& other) = delete;
|
||||
|
||||
void add_file(ifcopenshell::file& file, const ifcopenshell::geometry::Settings& settings);
|
||||
void add_file(IfcGeom::Iterator& iterator);
|
||||
void add_element(IfcGeom::Element* element);
|
||||
|
||||
std::vector<express::Entity> select_box(const express::Entity& entity, bool completely_within = false, double extend = -1.e-5) const;
|
||||
std::vector<express::Entity> select_box(const tree_point& point) const;
|
||||
std::vector<express::Entity> select_box(const tree_box& bounds, bool completely_within = false) const;
|
||||
|
||||
std::vector<express::Entity> select(const express::Entity& entity, bool completely_within = false, double extend = 0.0) const;
|
||||
std::vector<express::Entity> select(const IfcGeom::Element* element, bool completely_within = false, double extend = -1.e-5) const;
|
||||
std::vector<express::Entity> select(const tree_point& point, double extend = 0.0) const;
|
||||
std::vector<ray_intersection_result> select_ray(const tree_point& origin, const tree_point& direction, double length = 1000.) const;
|
||||
|
||||
std::vector<clash> clash_intersection_many(const std::vector<express::Base>& set_a, const std::vector<express::Base>& set_b, double tolerance = 0.002, bool check_all = true) const;
|
||||
std::vector<clash> clash_collision_many(const std::vector<express::Base>& set_a, const std::vector<express::Base>& set_b, bool allow_touching = false) const;
|
||||
std::vector<clash> clash_clearance_many(const std::vector<express::Base>& set_a, const std::vector<express::Base>& set_b, double clearance = 0.05, bool check_all = false) const;
|
||||
|
||||
const std::vector<double>& distances() const;
|
||||
const std::vector<double>& protrusion_distances() const;
|
||||
|
||||
bool enable_face_styles() const;
|
||||
void enable_face_styles(bool enable);
|
||||
const std::vector<ifcopenshell::geometry::taxonomy::style::ptr>& styles() const;
|
||||
|
||||
#ifdef WITH_HDF5
|
||||
void write_h5();
|
||||
#endif
|
||||
|
||||
std::string uint8_to_b64(const std::vector<uint8_t>& uuids_array) const;
|
||||
static bool is_manifold(const std::vector<int>& faces);
|
||||
|
||||
private:
|
||||
class impl;
|
||||
std::unique_ptr<impl> impl_;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,54 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#include "tree_plugin.h"
|
||||
|
||||
namespace {
|
||||
constexpr const char* tree_plugin_prefix = "geometry.tree.";
|
||||
}
|
||||
|
||||
const char* ifcopenshell::geometry::trees::tree_plugin_registration_symbol() {
|
||||
return "ifcopenshell_register_tree_plugin_v1";
|
||||
}
|
||||
|
||||
ifcopenshell::plugin::metadata ifcopenshell::geometry::trees::tree_plugin_metadata(const std::string& plugin_name) {
|
||||
plugin::metadata metadata;
|
||||
metadata.kind_ = plugin::kind::tree;
|
||||
metadata.id = std::string(tree_plugin_prefix) + plugin_name;
|
||||
return metadata;
|
||||
}
|
||||
|
||||
std::filesystem::path ifcopenshell::geometry::trees::tree_plugin_directory() {
|
||||
return plugin::module_directory(reinterpret_cast<const void*>(&ifcopenshell::geometry::trees::load_tree_plugins));
|
||||
}
|
||||
|
||||
void ifcopenshell::geometry::trees::load_tree_plugins(tree_registry& registry) {
|
||||
plugin::manager manager;
|
||||
manager.add_search_path(tree_plugin_directory());
|
||||
|
||||
for (const auto& path : manager.discover(tree_plugin_prefix)) {
|
||||
auto module = manager.load(path);
|
||||
if (module.meta().kind_ != plugin::kind::tree) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto register_plugin = module.get_alias<register_tree_plugin_fn>(tree_plugin_registration_symbol());
|
||||
register_plugin(registry, module);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef IFCOPENSHELL_TREE_PLUGIN_H
|
||||
#define IFCOPENSHELL_TREE_PLUGIN_H
|
||||
|
||||
#include "tree_registry.h"
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
namespace ifcopenshell {
|
||||
namespace geometry {
|
||||
namespace trees {
|
||||
|
||||
typedef void register_tree_plugin_fn(tree_registry&, const ifcopenshell::plugin::module&);
|
||||
|
||||
IFC_GEOM_API const char* tree_plugin_registration_symbol();
|
||||
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);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,144 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#include "tree_registry.h"
|
||||
|
||||
#include "tree_plugin.h"
|
||||
#include "../ifcparse/exception.h"
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
#include <mutex>
|
||||
|
||||
namespace {
|
||||
std::string tree_key(const std::string& backend_id) {
|
||||
return boost::to_lower_copy(backend_id);
|
||||
}
|
||||
|
||||
[[noreturn]] void unsupported_tree_operation(const std::string& backend_id, const std::string& operation) {
|
||||
throw ifcopenshell::exception("Tree backend '" + backend_id + "' does not support " + operation);
|
||||
}
|
||||
}
|
||||
|
||||
ifcopenshell::geometry::trees::abstract_tree::~abstract_tree() = default;
|
||||
|
||||
void ifcopenshell::geometry::trees::abstract_tree::add_file(ifcopenshell::file&, const ifcopenshell::geometry::Settings&) {
|
||||
unsupported_tree_operation(std::string(backend_id()), "add_file()");
|
||||
}
|
||||
|
||||
void ifcopenshell::geometry::trees::abstract_tree::add_element(IfcGeom::Element*) {
|
||||
unsupported_tree_operation(std::string(backend_id()), "add_element()");
|
||||
}
|
||||
|
||||
std::vector<express::Entity> ifcopenshell::geometry::trees::abstract_tree::select_box(const express::Entity&, bool, double) const {
|
||||
unsupported_tree_operation(std::string(backend_id()), "select_box(entity)");
|
||||
}
|
||||
|
||||
std::vector<express::Entity> ifcopenshell::geometry::trees::abstract_tree::select_box(const IfcGeom::tree_point&) const {
|
||||
unsupported_tree_operation(std::string(backend_id()), "select_box(point)");
|
||||
}
|
||||
|
||||
std::vector<express::Entity> ifcopenshell::geometry::trees::abstract_tree::select_box(const IfcGeom::tree_box&, bool) const {
|
||||
unsupported_tree_operation(std::string(backend_id()), "select_box(bounds)");
|
||||
}
|
||||
|
||||
std::vector<express::Entity> ifcopenshell::geometry::trees::abstract_tree::select(const express::Entity&, bool, double) const {
|
||||
unsupported_tree_operation(std::string(backend_id()), "select(entity)");
|
||||
}
|
||||
|
||||
std::vector<express::Entity> ifcopenshell::geometry::trees::abstract_tree::select(const IfcGeom::Element*, bool, double) const {
|
||||
unsupported_tree_operation(std::string(backend_id()), "select(element)");
|
||||
}
|
||||
|
||||
std::vector<express::Entity> ifcopenshell::geometry::trees::abstract_tree::select(const IfcGeom::tree_point&, double) const {
|
||||
unsupported_tree_operation(std::string(backend_id()), "select(point)");
|
||||
}
|
||||
|
||||
std::vector<IfcGeom::ray_intersection_result> ifcopenshell::geometry::trees::abstract_tree::select_ray(const IfcGeom::tree_point&, const IfcGeom::tree_point&, double) const {
|
||||
unsupported_tree_operation(std::string(backend_id()), "select_ray()");
|
||||
}
|
||||
|
||||
std::vector<IfcGeom::clash> ifcopenshell::geometry::trees::abstract_tree::clash_intersection_many(const std::vector<express::Entity>&, const std::vector<express::Entity>&, double, bool) const {
|
||||
unsupported_tree_operation(std::string(backend_id()), "clash_intersection_many()");
|
||||
}
|
||||
|
||||
std::vector<IfcGeom::clash> ifcopenshell::geometry::trees::abstract_tree::clash_collision_many(const std::vector<express::Entity>&, const std::vector<express::Entity>&, bool) const {
|
||||
unsupported_tree_operation(std::string(backend_id()), "clash_collision_many()");
|
||||
}
|
||||
|
||||
std::vector<IfcGeom::clash> ifcopenshell::geometry::trees::abstract_tree::clash_clearance_many(const std::vector<express::Entity>&, const std::vector<express::Entity>&, double, bool) const {
|
||||
unsupported_tree_operation(std::string(backend_id()), "clash_clearance_many()");
|
||||
}
|
||||
|
||||
const std::vector<double>& ifcopenshell::geometry::trees::abstract_tree::distances() const {
|
||||
unsupported_tree_operation(std::string(backend_id()), "distances()");
|
||||
}
|
||||
|
||||
const std::vector<double>& ifcopenshell::geometry::trees::abstract_tree::protrusion_distances() const {
|
||||
unsupported_tree_operation(std::string(backend_id()), "protrusion_distances()");
|
||||
}
|
||||
|
||||
bool ifcopenshell::geometry::trees::abstract_tree::enable_face_styles() const {
|
||||
unsupported_tree_operation(std::string(backend_id()), "enable_face_styles()");
|
||||
}
|
||||
|
||||
void ifcopenshell::geometry::trees::abstract_tree::enable_face_styles(bool) {
|
||||
unsupported_tree_operation(std::string(backend_id()), "enable_face_styles(bool)");
|
||||
}
|
||||
|
||||
const std::vector<ifcopenshell::geometry::taxonomy::style::ptr>& ifcopenshell::geometry::trees::abstract_tree::styles() const {
|
||||
unsupported_tree_operation(std::string(backend_id()), "styles()");
|
||||
}
|
||||
|
||||
#ifdef WITH_HDF5
|
||||
void ifcopenshell::geometry::trees::abstract_tree::write_h5() {
|
||||
unsupported_tree_operation(std::string(backend_id()), "write_h5()");
|
||||
}
|
||||
#endif
|
||||
|
||||
void ifcopenshell::geometry::trees::tree_registry::bind(const tree_info& info, create_fn create, const plugin::module& module) {
|
||||
entry entry;
|
||||
entry.info_ = info;
|
||||
entry.create_ = create;
|
||||
entry.module_ = module;
|
||||
entries_[tree_key(info.backend_id)] = entry;
|
||||
}
|
||||
|
||||
bool ifcopenshell::geometry::trees::tree_registry::has(const std::string& backend_id) const {
|
||||
return entries_.find(tree_key(backend_id)) != entries_.end();
|
||||
}
|
||||
|
||||
std::unique_ptr<ifcopenshell::geometry::trees::abstract_tree> ifcopenshell::geometry::trees::tree_registry::create(const std::string& backend_id) const {
|
||||
const auto iter = entries_.find(tree_key(backend_id));
|
||||
if (iter == entries_.end()) {
|
||||
throw ifcopenshell::exception("No geometry tree registered for " + backend_id);
|
||||
}
|
||||
return std::unique_ptr<abstract_tree>(iter->second.create_());
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef IFCOPENSHELL_TREE_REGISTRY_H
|
||||
#define IFCOPENSHELL_TREE_REGISTRY_H
|
||||
|
||||
#include "tree.h"
|
||||
#include "../plugin/plugin.h"
|
||||
|
||||
#include <boost/function.hpp>
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
namespace ifcopenshell {
|
||||
class file;
|
||||
|
||||
namespace geometry {
|
||||
class Settings;
|
||||
|
||||
namespace trees {
|
||||
|
||||
struct IFC_GEOM_API tree_info {
|
||||
std::string backend_id;
|
||||
};
|
||||
|
||||
class IFC_GEOM_API abstract_tree {
|
||||
public:
|
||||
virtual ~abstract_tree();
|
||||
|
||||
virtual std::string_view backend_id() const = 0;
|
||||
|
||||
virtual void add_file(ifcopenshell::file& file, const ifcopenshell::geometry::Settings& settings);
|
||||
virtual void add_element(IfcGeom::Element* element);
|
||||
|
||||
virtual std::vector<express::Entity> select_box(const express::Entity& entity, bool completely_within, double extend) const;
|
||||
virtual std::vector<express::Entity> select_box(const IfcGeom::tree_point& point) const;
|
||||
virtual std::vector<express::Entity> select_box(const IfcGeom::tree_box& bounds, bool completely_within) const;
|
||||
|
||||
virtual std::vector<express::Entity> select(const express::Entity& entity, bool completely_within, double extend) const;
|
||||
virtual std::vector<express::Entity> select(const IfcGeom::Element* element, bool completely_within, double extend) const;
|
||||
virtual std::vector<express::Entity> select(const IfcGeom::tree_point& point, double extend) const;
|
||||
virtual std::vector<IfcGeom::ray_intersection_result> select_ray(const IfcGeom::tree_point& origin, const IfcGeom::tree_point& direction, double length) const;
|
||||
|
||||
virtual std::vector<IfcGeom::clash> clash_intersection_many(const std::vector<express::Entity>& set_a, const std::vector<express::Entity>& set_b, double tolerance, bool check_all) const;
|
||||
virtual std::vector<IfcGeom::clash> clash_collision_many(const std::vector<express::Entity>& set_a, const std::vector<express::Entity>& set_b, bool allow_touching) const;
|
||||
virtual std::vector<IfcGeom::clash> clash_clearance_many(const std::vector<express::Entity>& set_a, const std::vector<express::Entity>& set_b, double clearance, bool check_all) const;
|
||||
|
||||
virtual const std::vector<double>& distances() const;
|
||||
virtual const std::vector<double>& protrusion_distances() const;
|
||||
virtual bool enable_face_styles() const;
|
||||
virtual void enable_face_styles(bool enable);
|
||||
virtual const std::vector<ifcopenshell::geometry::taxonomy::style::ptr>& styles() const;
|
||||
|
||||
#ifdef WITH_HDF5
|
||||
virtual void write_h5();
|
||||
#endif
|
||||
};
|
||||
|
||||
class IFC_GEOM_API tree_registry {
|
||||
public:
|
||||
typedef boost::function0<abstract_tree*> create_fn;
|
||||
|
||||
void bind(const tree_info& info, create_fn create, const ifcopenshell::plugin::module& module = ifcopenshell::plugin::module());
|
||||
bool has(const std::string& backend_id) const;
|
||||
std::unique_ptr<abstract_tree> create(const std::string& backend_id) const;
|
||||
|
||||
private:
|
||||
struct entry {
|
||||
tree_info info_;
|
||||
create_fn create_;
|
||||
ifcopenshell::plugin::module module_;
|
||||
};
|
||||
|
||||
std::map<std::string, entry> entries_;
|
||||
};
|
||||
|
||||
IFC_GEOM_API tree_registry& tree_registry_instance();
|
||||
IFC_GEOM_API std::unique_ptr<abstract_tree> construct(const std::string& backend_id);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user