mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-26 18:21:59 +00:00
Reuse more existing api in cgal face self-intersection detection #5820
This commit is contained in:
@@ -105,54 +105,35 @@ ifcopenshell::geometry::CgalShape::CgalShape(const cgal_shape_t& shape, bool con
|
|||||||
std::set<cgal_shape_t::Facet_handle> faces_to_remove;
|
std::set<cgal_shape_t::Facet_handle> faces_to_remove;
|
||||||
|
|
||||||
for (const auto& face : CGAL::faces(*shape_)) {
|
for (const auto& face : CGAL::faces(*shape_)) {
|
||||||
// @todo O^2 alert! Use aabb tree or box intersections
|
|
||||||
|
|
||||||
auto V = newell(*face).to_vector();
|
auto V = newell(*face).to_vector();
|
||||||
|
CGAL::Plane_3<Kernel_> plane(CGAL::Point_3<Kernel_>(), V);
|
||||||
|
auto b1 = plane.base1();
|
||||||
|
auto b2 = plane.base2();
|
||||||
|
|
||||||
if (V.squared_length() == 0) {
|
if (V.squared_length() == 0) {
|
||||||
Logger::Warning("Removed face due to self-intersections");
|
Logger::Warning("Removed face due to self-intersections");
|
||||||
faces_to_remove.insert(face);
|
faces_to_remove.insert(face);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
auto C = face->halfedge()->vertex()->point();
|
auto C = face->halfedge()->vertex()->point();
|
||||||
auto transform_point = [&V, &C](const auto& p) {
|
auto transform_point = [&V, &C, &b1, &b2](const auto& p) {
|
||||||
auto dv = p - C;
|
auto dv = p - C;
|
||||||
return C + (dv - (dv * V) * V);
|
return CGAL::Point_2<Kernel_>(
|
||||||
|
dv * b1,
|
||||||
|
dv * b2
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
std::vector<CGAL::Point_2<Kernel_>> ps;
|
||||||
|
|
||||||
for (auto& he1 : CGAL::halfedges_around_face(face->halfedge(), *shape_)) {
|
for (auto& he1 : CGAL::halfedges_around_face(face->halfedge(), *shape_)) {
|
||||||
CGAL::Segment_3<Kernel_> s1;
|
const auto& source = he1->vertex()->point();
|
||||||
{
|
ps.push_back(transform_point(source));
|
||||||
const auto& source = he1->vertex()->point();
|
}
|
||||||
const auto& target = he1->next()->vertex()->point();
|
|
||||||
s1 = {
|
if (!CGAL::Polygon_2<Kernel_>(ps.begin(), ps.end()).is_simple()) {
|
||||||
transform_point(source),
|
Logger::Warning("Removed face due to self-intersections");
|
||||||
transform_point(target)
|
faces_to_remove.insert(face);
|
||||||
};
|
|
||||||
}
|
|
||||||
for (auto& he2 : CGAL::halfedges_around_face(face->halfedge(), *shape_)) {
|
|
||||||
if (he1 == he2 || he1->next() == he2 || he2->next() == he1) {
|
|
||||||
// skip topologically connected edges
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
CGAL::Segment_3<Kernel_> s2;
|
|
||||||
{
|
|
||||||
const auto& source = he2->vertex()->point();
|
|
||||||
const auto& target = he2->next()->vertex()->point();
|
|
||||||
s2 = {
|
|
||||||
transform_point(source),
|
|
||||||
transform_point(target)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (CGAL::to_double((s1.start() - s2.end()).squared_length()) < 1.e-12 ||
|
|
||||||
CGAL::to_double((s1.end() - s2.end()).squared_length()) < 1.e-12 ||
|
|
||||||
CGAL::to_double((s1.start() - s2.start()).squared_length()) < 1.e-12 ||
|
|
||||||
CGAL::to_double((s1.end() - s2.start()).squared_length()) < 1.e-12 ||
|
|
||||||
CGAL::do_intersect(s1, s2))
|
|
||||||
{
|
|
||||||
Logger::Warning("Removed face due to self-intersections");
|
|
||||||
faces_to_remove.insert(face);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user