tree and document plug-ins

This commit is contained in:
Thomas Krijnen
2026-04-17 11:24:09 +02:00
parent 3824e7b449
commit d2cc66fdf0
60 changed files with 2207 additions and 766 deletions
+24
View File
@@ -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)
+3 -1
View File
@@ -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
+6 -25
View File
@@ -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)