dllimport/export #6926

This commit is contained in:
Thomas Krijnen
2025-09-26 14:24:49 +02:00
parent 21137b9268
commit ce91d296b6
44 changed files with 957 additions and 860 deletions
@@ -3,6 +3,8 @@
#include <CGAL/Polygon_mesh_processing/repair.h>
#include <CGAL/Polygon_mesh_processing/self_intersections.h>
#include <CGAL/Polygon_mesh_processing/polygon_soup_to_polygon_mesh.h>
#include <CGAL/Polygon_mesh_processing/polygon_mesh_to_polygon_soup.h>
#include "../../../ifcparse/IfcLogger.h"
#include "../../../ifcgeom/IfcGeomRepresentation.h"
@@ -19,6 +21,10 @@ using ifcopenshell::geometry::NumberEpeck;
#define NumberType NumberEpeck
#endif
#ifdef IFOPSH_SIMPLE_KERNEL
#define CgalShape SimpleCgalShape
#endif
typedef CGAL::Polyhedron_3<Kernel_> Polyhedron;
typedef Polyhedron::Facet_const_handle Facet_const_handle;
typedef Polyhedron::Halfedge_around_facet_const_circulator Halfedge_around_facet_circulator;
@@ -701,6 +707,43 @@ ConversionResultShape* ifcopenshell::geometry::CgalShape::intersect(ConversionRe
#endif
}
namespace {
template <typename Polyhedron>
void concatenate_polyhedra(Polyhedron& p1, const Polyhedron& p2) {
std::vector<cgal_point_t> points1, points2;
std::vector<std::vector<std::size_t>> faces1, faces2;
// Extract soups
CGAL::Polygon_mesh_processing::polygon_mesh_to_polygon_soup(p1, points1, faces1);
CGAL::Polygon_mesh_processing::polygon_mesh_to_polygon_soup(p2, points2, faces2);
// Offset indices in faces2 by current number of points in points1
std::size_t offset = points1.size();
for (auto& f : faces2) {
for (auto& idx : f) {
idx += offset;
}
}
// Merge soups
points1.insert(points1.end(), points2.begin(), points2.end());
faces1.insert(faces1.end(), faces2.begin(), faces2.end());
// Build merged polyhedron
Polyhedron merged;
CGAL::Polygon_mesh_processing::polygon_soup_to_polygon_mesh(points1, faces1, merged);
p1 = std::move(merged);
}
}
ConversionResultShape* ifcopenshell::geometry::CgalShape::concat(ConversionResultShape* other)
{
auto shp = poly();
concatenate_polyhedra(shp, ((CgalShape*)other)->poly());
return new CgalShape(shp);
}
std::pair<OpaqueCoordinate<3>, OpaqueCoordinate<3>> ifcopenshell::geometry::CgalShape::bounding_box() const
{
throw std::runtime_error("Not implemented");
@@ -736,6 +779,11 @@ void ifcopenshell::geometry::CgalShape::map(const std::vector<OpaqueCoordinate<4
throw std::runtime_error("Not implemented");
}
bool ifcopenshell::geometry::CgalShape::surface_area_along_direction(double tol, const ifcopenshell::geometry::taxonomy::matrix4::ptr& place, double& along_x, double& along_y, double& along_z) const {
// @todo
return false;
}
#ifndef IFOPSH_SIMPLE_KERNEL
void ifcopenshell::geometry::CgalShapeHalfSpaceDecomposition::Triangulate(ifcopenshell::geometry::Settings settings, const ifcopenshell::geometry::taxonomy::matrix4& place, IfcGeom::Representation::Triangulation* t, int item_id, int surface_style_id) const {
@@ -20,6 +20,8 @@
#ifndef CGALCONVERSIONRESULT_H
#define CGALCONVERSIONRESULT_H
#include "../../../ifcgeom/kernels/ifc_geomlibrary_api.h"
#include "../../../ifcgeom/IfcGeomElement.h"
#undef Handle
@@ -100,7 +102,7 @@ namespace ifcopenshell { namespace geometry {
using IfcGeom::negate_;
#ifndef IFOPSH_SIMPLE_KERNEL
class IFC_GEOM_API NumberEpeck : public OpaqueNumber {
class IFC_GEOMLIBRARY_API NumberEpeck : public OpaqueNumber {
private:
CGAL::Epeck::FT value_;
@@ -175,7 +177,7 @@ namespace ifcopenshell { namespace geometry {
};
#endif
class CgalShape : public IfcGeom::ConversionResultShape {
class IFC_GEOMLIBRARY_API CgalShape : public IfcGeom::ConversionResultShape {
private:
bool convex_tag_ = false;
mutable boost::optional<cgal_shape_t> shape_;
@@ -250,17 +252,20 @@ namespace ifcopenshell { namespace geometry {
virtual ConversionResultShape* add(ConversionResultShape*);
virtual ConversionResultShape* subtract(ConversionResultShape*);
virtual ConversionResultShape* intersect(ConversionResultShape*);
virtual ConversionResultShape* concat(ConversionResultShape*);
virtual void map(OpaqueCoordinate<4>& from, OpaqueCoordinate<4>& to);
virtual void map(const std::vector<OpaqueCoordinate<4>>& from, const std::vector<OpaqueCoordinate<4>>& to);
virtual ConversionResultShape* moved(ifcopenshell::geometry::taxonomy::matrix4::ptr) const;
virtual bool surface_area_along_direction(double tol, const ifcopenshell::geometry::taxonomy::matrix4::ptr&, double& along_x, double& along_y, double& along_z) const;
bool convex_tag() const { return convex_tag_; }
bool& convex_tag() { return convex_tag_; }
};
#ifndef IFOPSH_SIMPLE_KERNEL
class CgalShapeHalfSpaceDecomposition : public IfcGeom::ConversionResultShape {
class IFC_GEOMLIBRARY_API CgalShapeHalfSpaceDecomposition : public IfcGeom::ConversionResultShape {
private:
std::unique_ptr<halfspace_tree<Kernel_>> shape_;
std::list<CGAL::Plane_3<Kernel_>> planes_;
@@ -315,12 +320,23 @@ namespace ifcopenshell { namespace geometry {
virtual ConversionResultShape* add(ConversionResultShape*);
virtual ConversionResultShape* subtract(ConversionResultShape*);
virtual ConversionResultShape* intersect(ConversionResultShape*);
virtual ConversionResultShape* concat(ConversionResultShape*) {
return nullptr;
}
virtual void map(OpaqueCoordinate<4>& from, OpaqueCoordinate<4>& to);
virtual void map(const std::vector<OpaqueCoordinate<4>>& from, const std::vector<OpaqueCoordinate<4>>& to);
virtual ConversionResultShape* moved(ifcopenshell::geometry::taxonomy::matrix4::ptr) const;
virtual bool surface_area_along_direction(double tol, const ifcopenshell::geometry::taxonomy::matrix4::ptr&, double& along_x, double& along_y, double& along_z) const {
return false;
}
};
#endif
}}
#ifdef IFOPSH_SIMPLE_KERNEL
#undef CgalShape
#endif
#endif
+4
View File
@@ -24,6 +24,10 @@
#include "../../../ifcparse/IfcLogger.h"
#include "../../../ifcgeom/kernels/cgal/CgalConversionResult.h"
#ifdef IFOPSH_SIMPLE_KERNEL
#define CgalShape SimpleCgalShape
#endif
#include <CGAL/minkowski_sum_3.h>
#include <CGAL/exceptions.h>
+20 -7
View File
@@ -47,6 +47,7 @@ if ( it != cache.T.end() ) { e = it->second; return true; }
#include "../../../ifcgeom/IfcGeomElement.h"
#include "../../../ifcgeom/kernels/cgal/CgalConversionResult.h"
#include "../../../ifcgeom/kernels/ifc_geomlibrary_api.h"
#include <CGAL/Polygon_2.h>
@@ -55,20 +56,20 @@ if ( it != cache.T.end() ) { e = it->second; return true; }
namespace ifcopenshell {
namespace geometry {
namespace utils {
IFC_GEOM_API CGAL::Polyhedron_3<Kernel_> create_cube(double d);
IFC_GEOM_API CGAL::Polyhedron_3<Kernel_> create_cube(const Kernel_::Point_3& lower, const Kernel_::Point_3& upper);
IFC_GEOM_API CGAL::Polyhedron_3<Kernel_> create_polyhedron(std::list<cgal_face_t> &face_list, bool stitch_borders = false);
IFC_GEOMLIBRARY_API CGAL::Polyhedron_3<Kernel_> create_cube(double d);
IFC_GEOMLIBRARY_API CGAL::Polyhedron_3<Kernel_> create_cube(const Kernel_::Point_3& lower, const Kernel_::Point_3& upper);
IFC_GEOMLIBRARY_API CGAL::Polyhedron_3<Kernel_> create_polyhedron(std::list<cgal_face_t> &face_list, bool stitch_borders = false);
#ifndef IFOPSH_SIMPLE_KERNEL
IFC_GEOM_API CGAL::Polyhedron_3<Kernel_> create_polyhedron(const CGAL::Nef_polyhedron_3<Kernel_> &nef_polyhedron);
IFC_GEOM_API CGAL::Nef_polyhedron_3<Kernel_> create_nef_polyhedron(std::list<cgal_face_t> &face_list);
IFC_GEOM_API CGAL::Nef_polyhedron_3<Kernel_> create_nef_polyhedron(CGAL::Polyhedron_3<Kernel_> &polyhedron);
IFC_GEOMLIBRARY_API CGAL::Polyhedron_3<Kernel_> create_polyhedron(const CGAL::Nef_polyhedron_3<Kernel_> &nef_polyhedron);
IFC_GEOMLIBRARY_API CGAL::Nef_polyhedron_3<Kernel_> create_nef_polyhedron(std::list<cgal_face_t> &face_list);
IFC_GEOMLIBRARY_API CGAL::Nef_polyhedron_3<Kernel_> create_nef_polyhedron(CGAL::Polyhedron_3<Kernel_> &polyhedron);
#endif
}
namespace kernels {
class IFC_GEOM_API CgalKernel : public AbstractKernel {
class IFC_GEOMLIBRARY_API CgalKernel : public AbstractKernel {
private:
#ifndef IFOPSH_SIMPLE_KERNEL
enum boolean_operand_preprocess {
@@ -94,6 +95,18 @@ namespace ifcopenshell {
: AbstractKernel("cgal", settings)
{}
virtual AbstractKernel* clone() const {
return new CgalKernel(settings());
}
virtual bool supports_boolean_operations() const {
#ifndef IFOPSH_SIMPLE_KERNEL
return true;
#else
return false;
#endif
}
bool convert(const taxonomy::extrusion::ptr, cgal_shape_t&);
bool convert(const taxonomy::face::ptr, std::list<cgal_face_t>&);
bool convert(const taxonomy::loop::ptr, cgal_wire_t&);
+37
View File
@@ -0,0 +1,37 @@
/********************************************************************************
* *
* 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 IFC_GEOMLIBRARY_API_H
#define IFC_GEOMLIBRARY_API_H
#ifdef IFC_SHARED_BUILD
#ifdef _WIN32
#ifdef IFC_GEOMLIBRARY_EXPORTS
#define IFC_GEOMLIBRARY_API __declspec(dllexport)
#else
#define IFC_GEOMLIBRARY_API __declspec(dllimport)
#endif
#else // simply assume *nix + GCC-like compiler
#define IFC_GEOMLIBRARY_API __attribute__((visibility("default")))
#endif
#else
#define IFC_GEOMLIBRARY_API
#endif
#endif
@@ -25,6 +25,7 @@
#include "../../../ifcgeom/IfcGeomElement.h"
#include "../../../ifcgeom/Iterator.h"
#include "OpenCascadeConversionResult.h"
#include "OpenCascadeKernel.h"
#include "base_utils.h"
#include <NCollection_UBTree.hxx>
@@ -1503,7 +1504,7 @@ namespace IfcGeom {
settings_.get<ifcopenshell::geometry::settings::UseWorldCoords>().value = true;
settings_.get<ifcopenshell::geometry::settings::ReorientShells>().value = true;
IfcGeom::Iterator it(settings_, &f, {}, 1);
IfcGeom::Iterator it(std::unique_ptr<ifcopenshell::geometry::kernels::AbstractKernel>(new OpenCascadeKernel(settings_)), settings_, &f, {}, 1);
add_file(it);
}
@@ -7,6 +7,8 @@
#include <Geom_SphericalSurface.hxx>
#include <Geom_Plane.hxx>
#include <BRepTools_WireExplorer.hxx>
#include <TopoDS_Compound.hxx>
#include <BRep_Builder.hxx>
#include "OpenCascadeConversionResult.h"
@@ -546,6 +548,26 @@ ConversionResultShape* ifcopenshell::geometry::OpenCascadeShape::intersect(Conve
return boolean_op(BOPAlgo_COMMON, shape_, ((ifcopenshell::geometry::OpenCascadeShape*)other)->shape_);
}
ConversionResultShape* ifcopenshell::geometry::OpenCascadeShape::concat(ConversionResultShape* other)
{
TopoDS_Compound compound;
BRep_Builder builder;
auto& left = shape_;
auto& right = ((ifcopenshell::geometry::OpenCascadeShape*)other)->shape_;
if (left.ShapeType() == TopAbs_COMPOUND) {
compound = TopoDS::Compound(left);
} else {
builder.MakeCompound(compound);
builder.Add(compound, left);
}
builder.Add(compound, right);
return new OpenCascadeShape(std::move(compound));
}
std::pair<OpaqueCoordinate<3>, OpaqueCoordinate<3>> ifcopenshell::geometry::OpenCascadeShape::bounding_box() const
{
throw std::runtime_error("Not implemented");
@@ -556,6 +578,113 @@ ConversionResultShape* ifcopenshell::geometry::OpenCascadeShape::moved(ifcopensh
return new OpenCascadeShape(IfcGeom::util::apply_transformation(shape_, *t));
}
namespace {
void accumulate(const gp_Ax3& ax, const gp_Dir& normal, double area, double& along_x, double& along_y, double& along_z) {
along_x += area * fabs(ax.XDirection().Dot(normal));
along_y += area * fabs(ax.YDirection().Dot(normal));
along_z += area * fabs(ax.Direction().Dot(normal));
}
void surface_area_along_direction_(double tol, const TopoDS_Shape& s, const gp_Ax3& ax, double& along_x, double& along_y, double& along_z) {
along_x = along_y = along_z = 0.;
bool meshed = false;
TopExp_Explorer exp(s, TopAbs_FACE);
for (; exp.More(); exp.Next()) {
const TopoDS_Face& face = TopoDS::Face(exp.Current());
Handle(Geom_Surface) surf = BRep_Tool::Surface(face);
Handle(Geom_Plane) plane = Handle(Geom_Plane)::DownCast(surf);
if (surf->DynamicType() == STANDARD_TYPE(Geom_Plane)) {
GProp_GProps prop_area;
BRepGProp::SurfaceProperties(face, prop_area);
const double area = prop_area.Mass();
accumulate(ax, plane->Position().Direction(), area, along_x, along_y, along_z);
} else {
if (!meshed) {
try {
BRepMesh_IncrementalMesh(s, tol);
} catch (...) {
Logger::Message(Logger::LOG_ERROR, "Failed to triangulate shape");
return;
}
meshed = true;
}
TopLoc_Location loc;
Handle(Poly_Triangulation) tri = BRep_Tool::Triangulation(face, loc);
if (!tri.IsNull()) {
std::vector<gp_XYZ> coords;
coords.reserve(tri->NbNodes());
for (int i = 1; i <= tri->NbNodes(); ++i) {
coords.push_back(tri->Node(i).Transformed(loc).XYZ());
}
const Poly_Array1OfTriangle& triangles = tri->Triangles();
for (int i = 1; i <= triangles.Length(); ++i) {
int n1, n2, n3;
if (face.Orientation() == TopAbs_REVERSED) {
triangles(i).Get(n3, n2, n1);
} else {
triangles(i).Get(n1, n2, n3);
}
const gp_XYZ& pt1 = coords[n1 - 1];
const gp_XYZ& pt2 = coords[n2 - 1];
const gp_XYZ& pt3 = coords[n3 - 1];
const gp_Vec v1 = pt2 - pt1;
const gp_Vec v2 = pt3 - pt2;
const gp_Vec v3 = pt1 - pt3;
const gp_Vec normal_vector = v1 ^ v2;
if (normal_vector.Magnitude() > 1.e-7) {
gp_Dir normal = gp_Dir();
double edge_lengths[3] = { v1.Magnitude(), v2.Magnitude(), v3.Magnitude() };
std::sort(&edge_lengths[0], &edge_lengths[2]);
const double& a = edge_lengths[0];
const double& b = edge_lengths[1];
const double& c = edge_lengths[2];
const double area = 0.25 * sqrt((a + (b + c)) * (c - (a - b)) * (c + (a - b)) * (a + (b - c)));
accumulate(ax, normal, area, along_x, along_y, along_z);
}
}
}
}
}
}
}
bool ifcopenshell::geometry::OpenCascadeShape::surface_area_along_direction(double tol, const ifcopenshell::geometry::taxonomy::matrix4::ptr& place, double& along_x, double& along_y, double& along_z) const
{
gp_GTrsf trsf;
if (place->components_) {
gp_Trsf tr;
const auto& m = place->ccomponents();
tr.SetValues(
m(0, 0), m(0, 1), m(0, 2), m(0, 3),
m(1, 0), m(1, 1), m(1, 2), m(1, 3),
m(2, 0), m(2, 1), m(2, 2), m(2, 3)
);
trsf = tr;
}
gp_Mat mat = trsf.Trsf().HVectorialPart();
gp_Ax3 ax(trsf.TranslationPart(), mat.Column(3), mat.Column(1));
surface_area_along_direction_(tol, shape_, ax, along_x, along_y, along_z);
return true;
}
void ifcopenshell::geometry::OpenCascadeShape::map(OpaqueCoordinate<4>&, OpaqueCoordinate<4>&) {
throw std::runtime_error("Not implemented");
}
@@ -35,6 +35,7 @@
#include <GCPnts_QuasiUniformDeflection.hxx>
#include "../../../ifcgeom/ConversionResult.h"
#include "../../../ifcgeom/kernels/ifc_geomlibrary_api.h"
namespace ifcopenshell {
namespace geometry {
@@ -42,7 +43,7 @@ namespace ifcopenshell {
using IfcGeom::OpaqueCoordinate;
using IfcGeom::OpaqueNumber;
class OpenCascadeShape : public IfcGeom::ConversionResultShape {
class IFC_GEOMLIBRARY_API OpenCascadeShape : public IfcGeom::ConversionResultShape {
public:
OpenCascadeShape(const TopoDS_Shape& shape)
: shape_(shape) {}
@@ -97,10 +98,13 @@ namespace ifcopenshell {
virtual ConversionResultShape* add(ConversionResultShape*);
virtual ConversionResultShape* subtract(ConversionResultShape*);
virtual ConversionResultShape* intersect(ConversionResultShape*);
virtual ConversionResultShape* concat(ConversionResultShape*);
virtual void map(OpaqueCoordinate<4>& from, OpaqueCoordinate<4>& to);
virtual void map(const std::vector<OpaqueCoordinate<4>>& from, const std::vector<OpaqueCoordinate<4>>& to);
virtual ConversionResultShape* moved(ifcopenshell::geometry::taxonomy::matrix4::ptr) const;
virtual bool surface_area_along_direction(double tol, const ifcopenshell::geometry::taxonomy::matrix4::ptr&, double& along_x, double& along_y, double& along_z) const;
private:
TopoDS_Shape shape_;
};
@@ -51,14 +51,14 @@
#include "../../../ifcgeom/kernels/opencascade/OpenCascadeConversionResult.h"
#include "../../../ifcgeom/ifc_geom_api.h"
#include "../../../ifcgeom/kernels/ifc_geomlibrary_api.h"
#include "../../../ifcgeom/taxonomy.h"
#include "../../../ifcgeom/ConversionSettings.h"
namespace IfcGeom {
class IFC_GEOM_API OpenCascadeKernel : public ifcopenshell::geometry::kernels::AbstractKernel {
class IFC_GEOMLIBRARY_API OpenCascadeKernel : public ifcopenshell::geometry::kernels::AbstractKernel {
private:
/*
@@ -103,6 +103,12 @@ public:
, precision_(settings.get<ifcopenshell::geometry::settings::Precision>().get())
{}
virtual AbstractKernel* clone() const {
return new OpenCascadeKernel(settings());
}
virtual bool supports_boolean_operations() const { return true; }
bool convert(const ifcopenshell::geometry::taxonomy::extrusion::ptr, TopoDS_Shape&);
bool convert(const ifcopenshell::geometry::taxonomy::face::ptr, TopoDS_Shape&, bool reversed_surface = false);
bool convert(const ifcopenshell::geometry::taxonomy::loop::ptr, TopoDS_Wire&);
+60 -8
View File
@@ -4,6 +4,8 @@
#include "OpenCascadeConversionResult.h"
#include "boolean_utils.h"
#include <Standard_Version.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>
@@ -48,6 +50,8 @@
#include <TopTools_IndexedMapOfShape.hxx>
#include <ShapeUpgrade_UnifySameDomain.hxx>
// For axis placements detect equality early in order for the
// relatively computionaly expensive gp_Trsf calculation to be skipped
bool IfcGeom::util::axis_equal(const gp_Ax3 & a, const gp_Ax3 & b, double tolerance) {
@@ -297,18 +301,52 @@ TopoDS_Shape IfcGeom::util::apply_transformation(const TopoDS_Shape& s, const gp
}
}
namespace {
bool is_non_uniform(const Eigen::Matrix4d& M, double eps = 1e-6)
{
Eigen::Matrix3d L = M.block<3, 3>(0, 0);
double sx = L.col(0).norm();
double sy = L.col(1).norm();
double sz = L.col(2).norm();
return !(
std::abs(sx - sy) < eps &&
std::abs(sx - sz) < eps &&
std::abs(sy - sz) < eps
);
}
}
TopoDS_Shape IfcGeom::util::apply_transformation(const TopoDS_Shape& s, const ifcopenshell::geometry::taxonomy::matrix4& t) {
// @todo this probably discards non-uniform scale?
gp_GTrsf trsf;
if (t.components_) {
gp_Trsf tr;
const auto& m = t.ccomponents();
tr.SetValues(
m(0, 0), m(0, 1), m(0, 2), m(0, 3),
m(1, 0), m(1, 1), m(1, 2), m(1, 3),
m(2, 0), m(2, 1), m(2, 2), m(2, 3)
);
trsf = tr;
// This is either a bug or very finicky, but this appears to be the only
// way to get the transformation metadata to line up.
//
// - If gp_GTrsf.form is other, applying the transformation will result in
// a conversion to b-spline surfaces for about everything, which impacts
// performance and breaks detection of view volume in the svg serializer,
// which would be the case when setting the SetVectorialPart() block
// unconditionally.
// (calling SetForm() afterwards to detect CompoundTrsf over Other would
// set Scale to zero (bug?))
if (is_non_uniform(m)) {
trsf.SetVectorialPart(gp_Mat(
m(0, 0), m(0, 1), m(0, 2),
m(1, 0), m(1, 1), m(1, 2),
m(2, 0), m(2, 1), m(2, 2)
));
trsf.SetTranslationPart(gp_XYZ(m(0, 3), m(1, 3), m(2, 3)));
} else {
gp_Trsf tr;
tr.SetValues(
m(0, 0), m(0, 1), m(0, 2), m(0, 3),
m(1, 0), m(1, 1), m(1, 2), m(1, 3),
m(2, 0), m(2, 1), m(2, 2), m(2, 3)
);
trsf = tr;
}
}
return apply_transformation(s, trsf);
}
@@ -864,3 +902,17 @@ bool IfcGeom::util::validate_shape(const TopoDS_Shape& s) {
return false;
}
TopoDS_Shape IfcGeom::util::unify(const TopoDS_Shape& s, double tolerance) {
tolerance = (std::min)(min_edge_length(s) / 2., tolerance);
ShapeUpgrade_UnifySameDomain usd(s);
#if OCC_VERSION_HEX >= 0x70200
usd.SetSafeInputMode(true);
#endif
#if OCC_VERSION_HEX >= 0x70100
usd.SetLinearTolerance(tolerance);
usd.SetAngularTolerance(1.e-3);
#endif
usd.Build();
return usd.Shape();
}
+40 -37
View File
@@ -2,6 +2,7 @@
#define BASE_UTILS_H
#include "../../../ifcgeom/ConversionResult.h"
#include "../ifc_geomlibrary_api.h"
#include <gp_Pln.hxx>
#include <gp_Pnt.hxx>
@@ -25,58 +26,60 @@
namespace IfcGeom {
namespace util {
int count(const TopoDS_Shape&, TopAbs_ShapeEnum, bool unique = false);
int surface_genus(const TopoDS_Shape&);
IFC_GEOMLIBRARY_API int count(const TopoDS_Shape&, TopAbs_ShapeEnum, bool unique = false);
IFC_GEOMLIBRARY_API int surface_genus(const TopoDS_Shape&);
bool is_manifold(const TopoDS_Shape& a);
IFC_GEOMLIBRARY_API bool is_manifold(const TopoDS_Shape& a);
// For axis placements detect equality early in order for the
// relatively computionaly expensive gp_Trsf calculation to be skipped
bool axis_equal(const gp_Ax3& a, const gp_Ax3& b, double tolerance);
IFC_GEOMLIBRARY_API bool axis_equal(const gp_Ax3& a, const gp_Ax3& b, double tolerance);
bool axis_equal(const gp_Ax2d& a, const gp_Ax2d& b, double tolerance);
IFC_GEOMLIBRARY_API bool axis_equal(const gp_Ax2d& a, const gp_Ax2d& b, double tolerance);
bool is_identity(const gp_Trsf2d& t, double tolerance);
bool is_identity(const gp_GTrsf2d& t, double tolerance);
bool is_identity(const gp_Trsf& t, double tolerance);
bool is_identity(const gp_GTrsf& t, double tolerance);
IFC_GEOMLIBRARY_API bool is_identity(const gp_Trsf2d& t, double tolerance);
IFC_GEOMLIBRARY_API bool is_identity(const gp_GTrsf2d& t, double tolerance);
IFC_GEOMLIBRARY_API bool is_identity(const gp_Trsf& t, double tolerance);
IFC_GEOMLIBRARY_API bool is_identity(const gp_GTrsf& t, double tolerance);
gp_Trsf combine_offset_and_rotation(const gp_Vec &offset, const gp_Quaternion& rotation);
IFC_GEOMLIBRARY_API gp_Trsf combine_offset_and_rotation(const gp_Vec &offset, const gp_Quaternion& rotation);
bool is_nested_compound_of_solid(const TopoDS_Shape& s, int depth = 0);
IFC_GEOMLIBRARY_API bool is_nested_compound_of_solid(const TopoDS_Shape& s, int depth = 0);
// Creates a solid from a compound of faces. When there are multiple connected components,
// a compound of solids is returned.
bool create_solid_from_compound(const TopoDS_Shape& compound, TopoDS_Shape& solid, double tol);
bool shape_to_face_list(const TopoDS_Shape& s, TopTools_ListOfShape& li);
bool create_solid_from_faces(const TopTools_ListOfShape& face_list, TopoDS_Shape& solid, double tol, bool force_sewing = false);
bool is_compound(const TopoDS_Shape& shape);
bool is_convex(const TopoDS_Wire& wire, double tol);
TopoDS_Shape halfspace_from_plane(const gp_Pln& pln, const gp_Pnt& cent);
gp_Pln plane_from_face(const TopoDS_Face& face);
gp_Pnt point_above_plane(const gp_Pln& pln, bool agree = true);
IFC_GEOMLIBRARY_API bool create_solid_from_compound(const TopoDS_Shape& compound, TopoDS_Shape& solid, double tol);
IFC_GEOMLIBRARY_API bool shape_to_face_list(const TopoDS_Shape& s, TopTools_ListOfShape& li);
IFC_GEOMLIBRARY_API bool create_solid_from_faces(const TopTools_ListOfShape& face_list, TopoDS_Shape& solid, double tol, bool force_sewing = false);
IFC_GEOMLIBRARY_API bool is_compound(const TopoDS_Shape& shape);
IFC_GEOMLIBRARY_API bool is_convex(const TopoDS_Wire& wire, double tol);
IFC_GEOMLIBRARY_API TopoDS_Shape halfspace_from_plane(const gp_Pln& pln, const gp_Pnt& cent);
IFC_GEOMLIBRARY_API gp_Pln plane_from_face(const TopoDS_Face& face);
IFC_GEOMLIBRARY_API gp_Pnt point_above_plane(const gp_Pln& pln, bool agree = true);
bool fit_halfspace(const TopoDS_Shape& a, const TopoDS_Shape& b, TopoDS_Shape& box, double& height, double tol);
const Handle_Geom_Curve intersect(const Handle_Geom_Surface&, const Handle_Geom_Surface&);
const Handle_Geom_Curve intersect(const Handle_Geom_Surface&, const TopoDS_Face&);
const Handle_Geom_Curve intersect(const TopoDS_Face&, const Handle_Geom_Surface&);
bool intersect(const Handle_Geom_Curve&, const Handle_Geom_Surface&, gp_Pnt&);
bool intersect(const Handle_Geom_Curve&, const TopoDS_Face&, gp_Pnt&);
bool intersect(const Handle_Geom_Curve&, const TopoDS_Shape&, std::vector<gp_Pnt>&);
bool intersect(const Handle_Geom_Surface&, const TopoDS_Shape&, std::vector< std::pair<Handle_Geom_Surface, Handle_Geom_Curve> >&);
bool closest(const gp_Pnt&, const std::vector<gp_Pnt>&, gp_Pnt&);
bool project(const Handle_Geom_Curve&, const gp_Pnt&, gp_Pnt& p, double& u, double& d);
bool project(const Handle_Geom_Surface&, const TopoDS_Shape&, double& u1, double& v1, double& u2, double& v2, double widen = 0.1);
IFC_GEOMLIBRARY_API bool fit_halfspace(const TopoDS_Shape& a, const TopoDS_Shape& b, TopoDS_Shape& box, double& height, double tol);
IFC_GEOMLIBRARY_API const Handle_Geom_Curve intersect(const Handle_Geom_Surface&, const Handle_Geom_Surface&);
IFC_GEOMLIBRARY_API const Handle_Geom_Curve intersect(const Handle_Geom_Surface&, const TopoDS_Face&);
IFC_GEOMLIBRARY_API const Handle_Geom_Curve intersect(const TopoDS_Face&, const Handle_Geom_Surface&);
IFC_GEOMLIBRARY_API bool intersect(const Handle_Geom_Curve&, const Handle_Geom_Surface&, gp_Pnt&);
IFC_GEOMLIBRARY_API bool intersect(const Handle_Geom_Curve&, const TopoDS_Face&, gp_Pnt&);
IFC_GEOMLIBRARY_API bool intersect(const Handle_Geom_Curve&, const TopoDS_Shape&, std::vector<gp_Pnt>&);
IFC_GEOMLIBRARY_API bool intersect(const Handle_Geom_Surface&, const TopoDS_Shape&, std::vector< std::pair<Handle_Geom_Surface, Handle_Geom_Curve> >&);
IFC_GEOMLIBRARY_API bool closest(const gp_Pnt&, const std::vector<gp_Pnt>&, gp_Pnt&);
IFC_GEOMLIBRARY_API bool project(const Handle_Geom_Curve&, const gp_Pnt&, gp_Pnt& p, double& u, double& d);
IFC_GEOMLIBRARY_API bool project(const Handle_Geom_Surface&, const TopoDS_Shape&, double& u1, double& v1, double& u2, double& v2, double widen = 0.1);
double shape_volume(const TopoDS_Shape& s);
double face_area(const TopoDS_Face& f);
IFC_GEOMLIBRARY_API double shape_volume(const TopoDS_Shape& s);
IFC_GEOMLIBRARY_API double face_area(const TopoDS_Face& f);
TopoDS_Shape apply_transformation(const TopoDS_Shape&, const ifcopenshell::geometry::taxonomy::matrix4& t);
TopoDS_Shape apply_transformation(const TopoDS_Shape&, const gp_Trsf&);
TopoDS_Shape apply_transformation(const TopoDS_Shape&, const gp_GTrsf&);
IFC_GEOMLIBRARY_API TopoDS_Shape apply_transformation(const TopoDS_Shape&, const ifcopenshell::geometry::taxonomy::matrix4& t);
IFC_GEOMLIBRARY_API TopoDS_Shape apply_transformation(const TopoDS_Shape&, const gp_Trsf&);
IFC_GEOMLIBRARY_API TopoDS_Shape apply_transformation(const TopoDS_Shape&, const gp_GTrsf&);
bool flatten_shape_list(const IfcGeom::ConversionResults& shapes, TopoDS_Shape& result, bool fuse, bool create_shell, double tol);
bool validate_shape(const TopoDS_Shape&);
IFC_GEOMLIBRARY_API bool flatten_shape_list(const IfcGeom::ConversionResults& shapes, TopoDS_Shape& result, bool fuse, bool create_shell, double tol);
IFC_GEOMLIBRARY_API bool validate_shape(const TopoDS_Shape&);
IFC_GEOMLIBRARY_API TopoDS_Shape unify(const TopoDS_Shape& s, double tolerance);
}
}
@@ -13,7 +13,6 @@
#include <Extrema_ExtPC.hxx>
#include <Geom_Plane.hxx>
#include <Geom_BSplineCurve.hxx>
#include <ShapeUpgrade_UnifySameDomain.hxx>
#include <GeomAPI_ExtremaCurveCurve.hxx>
#include <ShapeAnalysis_Surface.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
@@ -575,20 +574,6 @@ int IfcGeom::util::eliminate_touching_operands(double prec, const TopoDS_Shape &
return N;
}
TopoDS_Shape IfcGeom::util::unify(const TopoDS_Shape & s, double tolerance) {
tolerance = (std::min)(min_edge_length(s) / 2., tolerance);
ShapeUpgrade_UnifySameDomain usd(s);
#if OCC_VERSION_HEX >= 0x70200
usd.SetSafeInputMode(true);
#endif
#if OCC_VERSION_HEX >= 0x70100
usd.SetLinearTolerance(tolerance);
usd.SetAngularTolerance(1.e-3);
#endif
usd.Build();
return usd.Shape();
}
bool IfcGeom::util::boolean_subtraction_2d_using_builder(const TopoDS_Shape & a_input, const TopTools_ListOfShape & b_input, TopoDS_Shape & result, double eps) {
IfcGeom::impl::tree<int> edge_tree;
@@ -30,6 +30,8 @@
#include <TopTools_IndexedMapOfShape.hxx>
#include <BOPAlgo_Operation.hxx>
#include "../ifc_geomlibrary_api.h"
namespace IfcGeom {
namespace util {
@@ -83,8 +85,6 @@ namespace IfcGeom {
int eliminate_narrow_operands(double prec, const TopTools_ListOfShape& bs, TopTools_ListOfShape & c);
TopoDS_Shape unify(const TopoDS_Shape& s, double tolerance);
bool boolean_subtraction_2d_using_builder(const TopoDS_Shape& a_input, const TopTools_ListOfShape& b_input, TopoDS_Shape& result, double eps);
struct boolean_settings {
@@ -3,27 +3,29 @@
#include <gp_Vec.hxx>
#include <array>
struct ray {
#include "../ifc_geomlibrary_api.h"
struct IFC_GEOMLIBRARY_API ray {
float origin[3];
float dir[3];
float dir_inv[3];
};
struct box {
struct IFC_GEOMLIBRARY_API box {
float corners[2][3];
};
bool is_intersect_ray_box(const struct ray *ray, const struct box *box);
IFC_GEOMLIBRARY_API bool is_intersect_ray_box(const struct ray *ray, const struct box *box);
bool intersectRayTriangle( const gp_Vec& orig, const gp_Vec& dir,
IFC_GEOMLIBRARY_API bool intersectRayTriangle( const gp_Vec& orig, const gp_Vec& dir,
const gp_Vec& vert0, const gp_Vec& vert1, const gp_Vec& vert2,
Standard_Real& at, Standard_Real& au, Standard_Real& av,
bool cull, float enlarge=0.0f);
void edgeEdgeDist(gp_Vec& x, gp_Vec& y, // closest points
IFC_GEOMLIBRARY_API void edgeEdgeDist(gp_Vec& x, gp_Vec& y, // closest points
const gp_Vec& p, const gp_Vec& a, // seg 1 origin, vector
const gp_Vec& q, const gp_Vec& b); // seg 2 origin, vector
float distanceTriangleTriangleSquared(gp_Vec& cp, gp_Vec& cq, const std::array<gp_Vec, 3> p, const std::array<gp_Vec, 3> q);
IFC_GEOMLIBRARY_API float distanceTriangleTriangleSquared(gp_Vec& cp, gp_Vec& cq, const std::array<gp_Vec, 3> p, const std::array<gp_Vec, 3> q);
bool trianglesIntersect(const gp_Vec& a1, const gp_Vec& b1, const gp_Vec& c1, const gp_Vec& a2, const gp_Vec& b2, const gp_Vec& c2/*, Segment* intersection*/, gp_Vec& int1, gp_Vec& int2, bool ignoreCoplanar);
IFC_GEOMLIBRARY_API bool trianglesIntersect(const gp_Vec& a1, const gp_Vec& b1, const gp_Vec& c1, const gp_Vec& a2, const gp_Vec& b2, const gp_Vec& c2/*, Segment* intersection*/, gp_Vec& int1, gp_Vec& int2, bool ignoreCoplanar);
+16 -14
View File
@@ -1,6 +1,8 @@
#ifndef WIRE_UTILS_H
#define WIRE_UTILS_H
#include "../ifc_geomlibrary_api.h"
#include <gp_Pln.hxx>
#include <Geom_Curve.hxx>
@@ -17,9 +19,9 @@
namespace IfcGeom {
namespace util {
bool approximate_plane_through_wire(const TopoDS_Wire& wire, gp_Pln& plane, double eps);
IFC_GEOMLIBRARY_API bool approximate_plane_through_wire(const TopoDS_Wire& wire, gp_Pln& plane, double eps);
bool flatten_wire(TopoDS_Wire& wire, double eps);
IFC_GEOMLIBRARY_API bool flatten_wire(TopoDS_Wire& wire, double eps);
enum triangulate_wire_result {
TRIANGULATE_WIRE_FAIL,
@@ -35,25 +37,25 @@ namespace IfcGeom {
};
/// Triangulate the set of wires. The firstmost wire is assumed to be the outer wire.
triangulate_wire_result triangulate_wire(const std::vector<TopoDS_Wire>& wires, TopTools_ListOfShape& faces);
IFC_GEOMLIBRARY_API triangulate_wire_result triangulate_wire(const std::vector<TopoDS_Wire>& wires, TopTools_ListOfShape& faces);
bool wire_intersections(const TopoDS_Wire& wire, TopTools_ListOfShape& wires, const wire_tolerance_settings& settings);
IFC_GEOMLIBRARY_API bool wire_intersections(const TopoDS_Wire& wire, TopTools_ListOfShape& wires, const wire_tolerance_settings& settings);
void select_largest(const TopTools_ListOfShape& shapes, TopoDS_Shape& largest);
IFC_GEOMLIBRARY_API void select_largest(const TopTools_ListOfShape& shapes, TopoDS_Shape& largest);
bool convert_wire_to_face(const TopoDS_Wire& wire, TopoDS_Face& face, const IfcGeom::util::wire_tolerance_settings& settings);
IFC_GEOMLIBRARY_API bool convert_wire_to_face(const TopoDS_Wire& wire, TopoDS_Face& face, const IfcGeom::util::wire_tolerance_settings& settings);
bool convert_wire_to_faces(const TopoDS_Wire& wire, TopoDS_Compound& face, const IfcGeom::util::wire_tolerance_settings& settings);
IFC_GEOMLIBRARY_API bool convert_wire_to_faces(const TopoDS_Wire& wire, TopoDS_Compound& face, const IfcGeom::util::wire_tolerance_settings& settings);
void assert_closed_wire(TopoDS_Wire& wire, double tol);
IFC_GEOMLIBRARY_API void assert_closed_wire(TopoDS_Wire& wire, double tol);
bool fill_nonmanifold_wires_with_planar_faces(TopoDS_Shape& shape, double tol);
void remove_duplicate_points_from_loop(TColgp_SequenceOfPnt& polygon, bool closed, double tol);
void remove_collinear_points_from_loop(TColgp_SequenceOfPnt& polygon, bool closed, double tol);
bool wire_to_sequence_of_point(const TopoDS_Wire&, TColgp_SequenceOfPnt&);
void sequence_of_point_to_wire(const TColgp_SequenceOfPnt&, TopoDS_Wire&, bool closed);
IFC_GEOMLIBRARY_API bool fill_nonmanifold_wires_with_planar_faces(TopoDS_Shape& shape, double tol);
IFC_GEOMLIBRARY_API void remove_duplicate_points_from_loop(TColgp_SequenceOfPnt& polygon, bool closed, double tol);
IFC_GEOMLIBRARY_API void remove_collinear_points_from_loop(TColgp_SequenceOfPnt& polygon, bool closed, double tol);
IFC_GEOMLIBRARY_API bool wire_to_sequence_of_point(const TopoDS_Wire&, TColgp_SequenceOfPnt&);
IFC_GEOMLIBRARY_API void sequence_of_point_to_wire(const TColgp_SequenceOfPnt&, TopoDS_Wire&, bool closed);
bool convert_curve_to_wire(const Handle(Geom_Curve)& curve, TopoDS_Wire& wire);
IFC_GEOMLIBRARY_API bool convert_curve_to_wire(const Handle(Geom_Curve)& curve, TopoDS_Wire& wire);
}
}