mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-10 06:00:51 +00:00
Merge remote-tracking branch 'origin/v0.8.0' into datamodel-v1.0
This commit is contained in:
@@ -1835,6 +1835,9 @@ bool CgalKernel::convert_impl(const taxonomy::boolean_result::ptr br, Conversion
|
||||
CGAL::Polygon_with_holes_2<Kernel_> pwh(p, ++it, loops.end());
|
||||
CGAL::Gps_segment_traits_2<Kernel_> traits;
|
||||
if (!CGAL::are_holes_and_boundary_pairwise_disjoint(pwh, traits)) {
|
||||
#ifdef IFOPSH_SIMPLE_KERNEL
|
||||
throw std::runtime_error("Holes are not disjoint - use a different geometry kernel");
|
||||
#else
|
||||
// this is very slow.
|
||||
// the check is also slow...
|
||||
|
||||
@@ -1851,6 +1854,7 @@ bool CgalKernel::convert_impl(const taxonomy::boolean_result::ptr br, Conversion
|
||||
result.difference(*it);
|
||||
}
|
||||
result.polygons_with_holes(std::back_inserter(pwhs));
|
||||
#endif
|
||||
} else {
|
||||
pwhs.push_back(pwh);
|
||||
}
|
||||
|
||||
@@ -1773,6 +1773,10 @@ namespace IfcGeom {
|
||||
auto& vs = elem->geometry().verts();
|
||||
auto& fs = elem->geometry().faces();
|
||||
|
||||
if (vs.empty() || fs.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
gp_Trsf tr;
|
||||
tr.SetValues(
|
||||
m(0, 0), m(0, 1), m(0, 2), m(0, 3),
|
||||
@@ -1840,23 +1844,36 @@ namespace IfcGeom {
|
||||
candidates.push_back({ std::abs(Z.Dot(ref)), ref });
|
||||
}
|
||||
|
||||
if (candidates.empty()) {
|
||||
{
|
||||
gp_XYZ ref(0, 0, 1);
|
||||
candidates.push_back({ std::abs(Z.Dot(ref)), ref });
|
||||
gp_Ax3 ax3;
|
||||
gp_Trsf trsf2;
|
||||
|
||||
for (size_t attempt = 0; attempt < 2; ++attempt) {
|
||||
|
||||
if (candidates.empty() || attempt == 1) {
|
||||
{
|
||||
gp_XYZ ref(0, 0, 1);
|
||||
candidates.push_back({std::abs(Z.Dot(ref)), ref});
|
||||
}
|
||||
{
|
||||
gp_XYZ ref(1, 0, 0);
|
||||
candidates.push_back({std::abs(Z.Dot(ref)), ref});
|
||||
}
|
||||
}
|
||||
|
||||
auto X = std::min_element(candidates.begin(), candidates.end(), [](auto& p1, auto& p2) { return p1.first < p2.first; })->second;
|
||||
|
||||
{
|
||||
gp_XYZ ref(1, 0, 0);
|
||||
candidates.push_back({ std::abs(Z.Dot(ref)), ref });
|
||||
try {
|
||||
ax3 = gp_Ax3(gp::Origin(), Z, X);
|
||||
trsf2.SetTransformation(gp::XOY(), ax3);
|
||||
} catch (Standard_ConstructionError&) {
|
||||
// Try again, likely we have all identical normals in candidates so
|
||||
// we cannot find a suitable candidate and need the two default axes
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto X = std::min_element(candidates.begin(), candidates.end(), [](auto& p1, auto& p2) { return p1.first < p2.first; })->second;
|
||||
|
||||
gp_Trsf trsf2;
|
||||
gp_Ax3 ax3(gp::Origin(), Z, X);
|
||||
trsf2.SetTransformation(gp::XOY(), ax3);
|
||||
|
||||
Bnd_Box tmp;
|
||||
|
||||
for (auto& p : vs_transformed) {
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "boolean_utils.h"
|
||||
#include "base_utils.h"
|
||||
|
||||
#include <BOPAlgo_MakerVolume.hxx>
|
||||
#include <BRepPrimAPI_MakeRevol.hxx>
|
||||
|
||||
namespace {
|
||||
@@ -136,7 +137,20 @@ bool IfcGeom::OpenCascadeKernel::convert_openings(const express::Base& entity, c
|
||||
bool is_manifold = util::is_manifold(entity_part);
|
||||
|
||||
if (!is_manifold) {
|
||||
logger::warning("Non-manifold first operand");
|
||||
if (settings_.get<settings::MakeVolume>().get()) {
|
||||
BOPAlgo_MakerVolume mv;
|
||||
mv.AddArgument(entity_part);
|
||||
mv.Perform();
|
||||
if (mv.HasErrors()) {
|
||||
logger::warning("Non-manifold first operand, --make-volume failed");
|
||||
} else {
|
||||
entity_part = mv.Shape();
|
||||
is_manifold = util::is_manifold(entity_part);
|
||||
}
|
||||
}
|
||||
if (!is_manifold) {
|
||||
logger::warning("Non-manifold first operand, use --make-volume to try and make manifold");
|
||||
}
|
||||
}
|
||||
|
||||
TopoDS_Shape entity_part_result;
|
||||
@@ -1363,4 +1377,4 @@ bool IfcGeom::OpenCascadeKernel::convert_impl(const taxonomy::revolve::ptr r, If
|
||||
// if (IfcGeom::util::apply_layerset(r, const std::vector<ifcopenshell::geometry::taxonomy::style>&, ConversionResults& r2, double tol)) {
|
||||
// std::swap(r, r2)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
@@ -56,6 +56,21 @@
|
||||
#include "../../../ifcgeom/taxonomy.h"
|
||||
#include "../../../ifcgeom/ConversionSettings.h"
|
||||
|
||||
namespace {
|
||||
template <typename Fn>
|
||||
bool handle_occt_exception(Fn&& fn) {
|
||||
try {
|
||||
return std::forward<Fn>(fn)();
|
||||
} catch (const Standard_Failure& e) {
|
||||
if (e.GetMessageString() && strlen(e.GetMessageString())) {
|
||||
throw std::runtime_error(e.GetMessageString());
|
||||
} else {
|
||||
throw std::runtime_error("Unknown error creating geometry");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace IfcGeom {
|
||||
|
||||
class IFC_GEOMLIBRARY_API OpenCascadeKernel : public ifcopenshell::geometry::kernels::AbstractKernel {
|
||||
|
||||
@@ -84,6 +84,7 @@ namespace {
|
||||
}
|
||||
|
||||
bool OpenCascadeKernel::convert_impl(const taxonomy::boolean_result::ptr br, ConversionResults& results) {
|
||||
return handle_occt_exception([&]() -> bool {
|
||||
bool valid_result = false;
|
||||
bool first = true;
|
||||
const double tol = settings_.get<settings::Precision>().get();
|
||||
@@ -196,4 +197,5 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::boolean_result::ptr br, Con
|
||||
));
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1134,6 +1134,8 @@ bool IfcGeom::util::boolean_operation(const boolean_settings& settings, const To
|
||||
#endif
|
||||
builder->SetFuzzyValue(fuzz);
|
||||
builder->SetArguments(s1s);
|
||||
// We use our own multi-threading in ifcopenshell on a per-product basis
|
||||
builder->SetRunParallel(false);
|
||||
copy_operand(b, b_tmp);
|
||||
std::swap(b, b_tmp);
|
||||
builder->SetTools(b);
|
||||
|
||||
@@ -72,6 +72,8 @@ bool OpenCascadeKernel::convert(const taxonomy::extrusion::ptr extrusion, TopoDS
|
||||
}
|
||||
|
||||
bool OpenCascadeKernel::convert_impl(const taxonomy::extrusion::ptr extrusion, IfcGeom::ConversionResults& results) {
|
||||
return handle_occt_exception([&]() -> bool {
|
||||
|
||||
TopoDS_Shape shape;
|
||||
if (!convert(extrusion, shape)) {
|
||||
return false;
|
||||
@@ -84,4 +86,6 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::extrusion::ptr extrusion, I
|
||||
extrusion->surface_style
|
||||
));
|
||||
return true;
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@@ -599,6 +599,8 @@ bool OpenCascadeKernel::convert(const taxonomy::face::ptr face, TopoDS_Shape& re
|
||||
}
|
||||
|
||||
bool OpenCascadeKernel::convert_impl(const taxonomy::face::ptr face, IfcGeom::ConversionResults& results) {
|
||||
return handle_occt_exception([&]() -> bool {
|
||||
|
||||
TopoDS_Shape shape;
|
||||
if (!convert(face, shape)) {
|
||||
return false;
|
||||
@@ -609,4 +611,6 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::face::ptr face, IfcGeom::Co
|
||||
face->surface_style
|
||||
));
|
||||
return true;
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@@ -107,6 +107,8 @@ bool OpenCascadeKernel::convert(const taxonomy::shell::ptr l, TopoDS_Shape& shap
|
||||
}
|
||||
|
||||
bool OpenCascadeKernel::convert_impl(const taxonomy::shell::ptr shell, IfcGeom::ConversionResults& results) {
|
||||
return handle_occt_exception([&]() -> bool {
|
||||
|
||||
TopoDS_Shape shape;
|
||||
if (!convert(shell, shape)) {
|
||||
return false;
|
||||
@@ -118,4 +120,6 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::shell::ptr shell, IfcGeom::
|
||||
shell->surface_style
|
||||
));
|
||||
return true;
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@@ -102,6 +102,8 @@ bool OpenCascadeKernel::convert(const taxonomy::solid::ptr solid, TopoDS_Shape&
|
||||
}
|
||||
|
||||
bool OpenCascadeKernel::convert_impl(const taxonomy::solid::ptr solid, IfcGeom::ConversionResults& results) {
|
||||
return handle_occt_exception([&]() -> bool {
|
||||
|
||||
TopoDS_Shape shape;
|
||||
if (!convert(solid, shape)) {
|
||||
return false;
|
||||
@@ -113,4 +115,6 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::solid::ptr solid, IfcGeom::
|
||||
solid->surface_style
|
||||
));
|
||||
return true;
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@@ -308,6 +308,8 @@ bool OpenCascadeKernel::convert(const taxonomy::sweep_along_curve::ptr scs, Topo
|
||||
}
|
||||
|
||||
bool OpenCascadeKernel::convert_impl(const taxonomy::sweep_along_curve::ptr scs, IfcGeom::ConversionResults& results) {
|
||||
return handle_occt_exception([&]() -> bool {
|
||||
|
||||
TopoDS_Shape shape;
|
||||
// For tiny radii occt will fail building the sweep, in which case we enlarge the inputs to occt, and add a scale matrix to the output
|
||||
bool enlarged = false;
|
||||
@@ -352,4 +354,6 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::sweep_along_curve::ptr scs,
|
||||
scs->surface_style
|
||||
));
|
||||
return true;
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user