mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-19 06:39:13 +00:00
Use custom poly converter
This commit is contained in:
@@ -29,7 +29,12 @@ ifcopenshell::geometry::CgalShape::CgalShape(const cgal_shape_t & shape) {
|
|||||||
void ifcopenshell::geometry::CgalShape::to_poly() const {
|
void ifcopenshell::geometry::CgalShape::to_poly() const {
|
||||||
if (!shape_) {
|
if (!shape_) {
|
||||||
shape_.emplace();
|
shape_.emplace();
|
||||||
nef_->convert_to_polyhedron(*shape_);
|
|
||||||
|
convert_to_polyhedron(*nef_, *shape_);
|
||||||
|
// @todo why is this necessary? we have the mark of the volumes?
|
||||||
|
CGAL::Polygon_mesh_processing::orient(*shape_);
|
||||||
|
|
||||||
|
// nef_->convert_to_polyhedron(*shape_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1003,7 +1003,7 @@ struct Halffacet_collector {
|
|||||||
// Visitor for Nef_polyhedron_3 shells to convert facets to Polyhedron_3
|
// Visitor for Nef_polyhedron_3 shells to convert facets to Polyhedron_3
|
||||||
// using the Polygon_mesh_processing package and Polygon_triangulation_decomposition_2
|
// using the Polygon_mesh_processing package and Polygon_triangulation_decomposition_2
|
||||||
// in case of facets with inner bounds.
|
// in case of facets with inner bounds.
|
||||||
template <typename Kernel>
|
template <typename Kernel, bool eliminate_tiny_facets=false>
|
||||||
class Polysoup_builder {
|
class Polysoup_builder {
|
||||||
private:
|
private:
|
||||||
std::map<CGAL::Point_3<Kernel>, size_t> verts;
|
std::map<CGAL::Point_3<Kernel>, size_t> verts;
|
||||||
@@ -1012,6 +1012,18 @@ public:
|
|||||||
void visit(typename CGAL::Nef_polyhedron_3<Kernel>::Vertex_const_handle) {}
|
void visit(typename CGAL::Nef_polyhedron_3<Kernel>::Vertex_const_handle) {}
|
||||||
void visit(typename CGAL::Nef_polyhedron_3<Kernel>::Halfedge_const_handle) {}
|
void visit(typename CGAL::Nef_polyhedron_3<Kernel>::Halfedge_const_handle) {}
|
||||||
void visit(typename CGAL::Nef_polyhedron_3<Kernel>::Halffacet_const_handle h) {
|
void visit(typename CGAL::Nef_polyhedron_3<Kernel>::Halffacet_const_handle h) {
|
||||||
|
// reduce extent of number because otherwise run into float_max
|
||||||
|
auto h_plane_ = h->plane();
|
||||||
|
std::array<typename Kernel::FT, 3> abc{ h_plane_.a(), h_plane_.b(), h_plane_.c() };
|
||||||
|
auto minel = std::min_element(abc.begin(), abc.end());
|
||||||
|
auto maxel = std::max_element(abc.begin(), abc.end());
|
||||||
|
auto maxval = ((-*minel) > *maxel) ? (-*minel) : *maxel;
|
||||||
|
CGAL::Plane_3<Kernel> h_plane(
|
||||||
|
h_plane_.a() / maxval,
|
||||||
|
h_plane_.b() / maxval,
|
||||||
|
h_plane_.c() / maxval,
|
||||||
|
h_plane_.d() / maxval
|
||||||
|
);
|
||||||
|
|
||||||
auto verts_backup = verts;
|
auto verts_backup = verts;
|
||||||
auto facets_backup = facets;
|
auto facets_backup = facets;
|
||||||
@@ -1019,9 +1031,9 @@ public:
|
|||||||
boost::optional<CGAL::Polygon_with_holes_2<Kernel>> pwh;
|
boost::optional<CGAL::Polygon_with_holes_2<Kernel>> pwh;
|
||||||
auto nf = std::distance(h->facet_cycles_begin(), h->facet_cycles_end());
|
auto nf = std::distance(h->facet_cycles_begin(), h->facet_cycles_end());
|
||||||
for (auto fc = h->facet_cycles_begin(); fc != h->facet_cycles_end(); ++fc) {
|
for (auto fc = h->facet_cycles_begin(); fc != h->facet_cycles_end(); ++fc) {
|
||||||
// std::cout << "h->plane().point() " << h->plane().point() << std::endl;
|
// std::cout << "h_plane.point() " << h_plane.point() << std::endl;
|
||||||
// std::cout << "h->plane().base1() " << h->plane().base1() << std::endl;
|
// std::cout << "h_plane.base1() " << h_plane.base1() << std::endl;
|
||||||
// std::cout << "h->plane().base2() " << h->plane().base2() << std::endl;
|
// std::cout << "h_plane.base2() " << h_plane.base2() << std::endl;
|
||||||
|
|
||||||
auto se = typename CGAL::Nef_polyhedron_3<Kernel>::SHalfedge_const_handle(fc);
|
auto se = typename CGAL::Nef_polyhedron_3<Kernel>::SHalfedge_const_handle(fc);
|
||||||
CGAL_assertion(se != 0);
|
CGAL_assertion(se != 0);
|
||||||
@@ -1039,9 +1051,9 @@ public:
|
|||||||
facets.back().push_back(verts.insert({ p , verts.size() }).first->second);
|
facets.back().push_back(verts.insert({ p , verts.size() }).first->second);
|
||||||
} else {
|
} else {
|
||||||
// std::cout << "p " << p << std::endl;
|
// std::cout << "p " << p << std::endl;
|
||||||
auto v = p - h->plane().point();
|
auto v = p - h_plane.point();
|
||||||
// std::cout << "v " << v << std::endl;
|
// std::cout << "v " << v << std::endl;
|
||||||
CGAL::Point_2<Kernel> uv(v * h->plane().base1(), v * h->plane().base2());
|
CGAL::Point_2<Kernel> uv(v * h_plane.base1(), v * h_plane.base2());
|
||||||
// std::cout << "uv " << uv << std::endl;
|
// std::cout << "uv " << uv << std::endl;
|
||||||
loop.push_back(uv);
|
loop.push_back(uv);
|
||||||
}
|
}
|
||||||
@@ -1062,53 +1074,60 @@ public:
|
|||||||
facets.emplace_back();
|
facets.emplace_back();
|
||||||
for (auto it = p.vertices_begin(); it != p.vertices_end(); ++it) {
|
for (auto it = p.vertices_begin(); it != p.vertices_end(); ++it) {
|
||||||
// std::cout << "*it " << *it << std::endl;
|
// std::cout << "*it " << *it << std::endl;
|
||||||
auto du = it->x() * h->plane().base1() / h->plane().base1().squared_length();
|
auto du = it->x() * h_plane.base1() / h_plane.base1().squared_length();
|
||||||
auto dv = it->y() * h->plane().base2() / h->plane().base2().squared_length();
|
auto dv = it->y() * h_plane.base2() / h_plane.base2().squared_length();
|
||||||
auto pp = h->plane().point() + du + dv;
|
auto pp = h_plane.point() + du + dv;
|
||||||
// std::cout << "pp " << pp << std::endl;
|
// std::cout << "pp " << pp << std::endl;
|
||||||
facets.back().push_back(verts.insert({ pp, verts.size() }).first->second);
|
facets.back().push_back(verts.insert({ pp, verts.size() }).first->second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Eliminate small slivers that create topologic connections between interior and exterior.
|
if constexpr (eliminate_tiny_facets) {
|
||||||
// Use connected components on polyhedron to eliminate.
|
// Eliminate small slivers that create topologic connections between interior and exterior.
|
||||||
|
// Use connected components on polyhedron to eliminate.
|
||||||
|
|
||||||
std::vector<const CGAL::Point_3<Kernel>*> verts_vector(verts.size());
|
std::vector<const CGAL::Point_3<Kernel>*> verts_vector(verts.size());
|
||||||
for (auto& p : verts) {
|
for (auto& p : verts) {
|
||||||
verts_vector[p.second] = &p.first;
|
verts_vector[p.second] = &p.first;
|
||||||
}
|
|
||||||
|
|
||||||
// We need to normalize because we want to compare to a real-world area value
|
|
||||||
auto b1 = h->plane().base1();
|
|
||||||
double l = std::sqrt(CGAL::to_double(b1.squared_length()));
|
|
||||||
b1 /= l;
|
|
||||||
|
|
||||||
auto b2 = h->plane().base2();
|
|
||||||
l = std::sqrt(CGAL::to_double(b2.squared_length()));
|
|
||||||
b2 /= l;
|
|
||||||
|
|
||||||
// check for size of emitted facet, rollback if too insignificant
|
|
||||||
typename Kernel::FT area = 0;
|
|
||||||
for (auto it = facets.begin() + facets_backup.size(); it != facets.end(); ++it) {
|
|
||||||
CGAL::Polygon_2<Kernel> loop;
|
|
||||||
for (auto& i : *it) {
|
|
||||||
const auto& p = *verts_vector[i];
|
|
||||||
auto v = p - h->plane().point();
|
|
||||||
// std::cout << "v " << v << std::endl;
|
|
||||||
CGAL::Point_2<Kernel> uv(v * b1, v * b2);
|
|
||||||
// std::cout << "uv " << uv << std::endl;
|
|
||||||
loop.push_back(uv);
|
|
||||||
}
|
}
|
||||||
area += loop.area();
|
|
||||||
}
|
|
||||||
|
|
||||||
// auto pl = h->plane();
|
// We need to normalize because we want to compare to a real-world area value
|
||||||
// l = std::sqrt(CGAL::to_double(pl.orthogonal_vector().squared_length()));
|
auto b1 = h_plane.base1();
|
||||||
// std::cout << pl.a() / l << " " << pl.b() / l << " " << pl.c() / l << " " << pl.d() / l << ": " << area << std::endl;
|
double l = std::sqrt(CGAL::to_double(b1.squared_length()));
|
||||||
if (area < 1.e-5) {
|
b1 /= l;
|
||||||
verts = verts_backup;
|
|
||||||
facets = facets_backup;
|
auto b2 = h_plane.base2();
|
||||||
|
l = std::sqrt(CGAL::to_double(b2.squared_length()));
|
||||||
|
b2 /= l;
|
||||||
|
|
||||||
|
// std::cout << "p " << h_plane << std::endl;
|
||||||
|
// std::cout << "x " << b1 << std::endl;
|
||||||
|
// std::cout << "y " << b2 << std::endl;
|
||||||
|
|
||||||
|
// check for size of emitted facet, rollback if too insignificant
|
||||||
|
typename Kernel::FT area = 0;
|
||||||
|
for (auto it = facets.begin() + facets_backup.size(); it != facets.end(); ++it) {
|
||||||
|
CGAL::Polygon_2<Kernel> loop;
|
||||||
|
for (auto& i : *it) {
|
||||||
|
const auto& p = *verts_vector[i];
|
||||||
|
auto v = p - h_plane.point();
|
||||||
|
// std::cout << "v " << v << std::endl;
|
||||||
|
CGAL::Point_2<Kernel> uv(v * b1, v * b2);
|
||||||
|
// std::cout << "uv " << uv << std::endl;
|
||||||
|
loop.push_back(uv);
|
||||||
|
}
|
||||||
|
// std::cout << "---" << std::endl;
|
||||||
|
area += loop.area();
|
||||||
|
}
|
||||||
|
|
||||||
|
// auto pl = h_plane;
|
||||||
|
// l = std::sqrt(CGAL::to_double(pl.orthogonal_vector().squared_length()));
|
||||||
|
// std::cout << pl.a() / l << " " << pl.b() / l << " " << pl.c() / l << " " << pl.d() / l << ": " << area << std::endl;
|
||||||
|
if (area < 1.e-5) {
|
||||||
|
verts = verts_backup;
|
||||||
|
facets = facets_backup;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void visit(typename CGAL::Nef_polyhedron_3<Kernel>::SHalfedge_const_handle) {}
|
void visit(typename CGAL::Nef_polyhedron_3<Kernel>::SHalfedge_const_handle) {}
|
||||||
|
|||||||
Reference in New Issue
Block a user