mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-11 22:31:55 +00:00
Correct projection to middle surface
This commit is contained in:
@@ -1576,15 +1576,14 @@ namespace {
|
|||||||
|
|
||||||
cgal_shape_t polyhedron, polyhedron2, flattened;
|
cgal_shape_t polyhedron, polyhedron2, flattened;
|
||||||
|
|
||||||
remove_thickness(const cgal_shape_t& p)
|
remove_thickness(const cgal_shape_t& p)
|
||||||
// edge_collapse(p) still does not work :(
|
// edge_collapse(p) still does not work :(
|
||||||
: polyhedron(p)
|
: polyhedron(p)
|
||||||
, polyhedron2(p)
|
, polyhedron2(p) {
|
||||||
{
|
|
||||||
CGAL::Polygon_mesh_processing::triangulate_faces(polyhedron);
|
CGAL::Polygon_mesh_processing::triangulate_faces(polyhedron);
|
||||||
CGAL::Polygon_mesh_processing::triangulate_faces(polyhedron2);
|
CGAL::Polygon_mesh_processing::triangulate_faces(polyhedron2);
|
||||||
|
|
||||||
std::list<cgal_shape_t::Facet_handle> non_degenerate, longitudonal;
|
std::list<cgal_shape_t::Facet_handle> non_degenerate, degenerate, longitudonal;
|
||||||
std::set<cgal_shape_t::Facet_iterator> thin_sides;
|
std::set<cgal_shape_t::Facet_iterator> thin_sides;
|
||||||
|
|
||||||
std::wcout << "ALL FACES:" << std::endl;
|
std::wcout << "ALL FACES:" << std::endl;
|
||||||
@@ -1593,6 +1592,9 @@ namespace {
|
|||||||
dump_facet(f);
|
dump_facet(f);
|
||||||
if (facet_area(f) > 1.e-20) {
|
if (facet_area(f) > 1.e-20) {
|
||||||
non_degenerate.push_back(f);
|
non_degenerate.push_back(f);
|
||||||
|
} else {
|
||||||
|
degenerate.push_front(f);
|
||||||
|
std::wcout << "Degenerate, area: " << facet_area(f) << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1606,20 +1608,41 @@ namespace {
|
|||||||
bo.input = non_degenerate;
|
bo.input = non_degenerate;
|
||||||
enlarged_non_degenerate_triangles.delegate(bo);
|
enlarged_non_degenerate_triangles.delegate(bo);
|
||||||
|
|
||||||
Tree tree(non_degenerate.begin(), non_degenerate.end(), polyhedron);
|
// @todo, first on non-enlarged faces, then on enlarged; to fix projection on concave surfaces where the enlarging operation shortens projection distances.
|
||||||
|
|
||||||
|
Tree tree(faces(enlarged_non_degenerate_triangles).first, faces(enlarged_non_degenerate_triangles).second, enlarged_non_degenerate_triangles);
|
||||||
|
|
||||||
std::map<cgal_face_descriptor_t, Kernel_::Vector_3> face_normals;
|
std::map<cgal_face_descriptor_t, Kernel_::Vector_3> face_normals;
|
||||||
boost::associative_property_map<std::map<cgal_face_descriptor_t, Kernel_::Vector_3>> face_normals_map(face_normals);
|
boost::associative_property_map<std::map<cgal_face_descriptor_t, Kernel_::Vector_3>> face_normals_map(face_normals);
|
||||||
CGAL::Polygon_mesh_processing::compute_face_normals(polyhedron, face_normals_map);
|
CGAL::Polygon_mesh_processing::compute_face_normals(polyhedron, face_normals_map);
|
||||||
|
|
||||||
for (auto& f : non_degenerate) {
|
for (auto& f : non_degenerate) {
|
||||||
auto O = CGAL::centroid(
|
auto O = CGAL::centroid(
|
||||||
f->facet_begin()->vertex()->point(),
|
f->facet_begin()->vertex()->point(),
|
||||||
f->facet_begin()->next()->vertex()->point(),
|
f->facet_begin()->next()->vertex()->point(),
|
||||||
f->facet_begin()->next()->next()->vertex()->point()
|
f->facet_begin()->next()->next()->vertex()->point()
|
||||||
);
|
);
|
||||||
|
|
||||||
Ray ray(O, -face_normals_map[f]);
|
Ray ray(O, -face_normals_map[f]);
|
||||||
|
|
||||||
|
std::list<Ray_intersection> intersections;
|
||||||
|
tree.all_intersections(ray, std::back_inserter(intersections));
|
||||||
|
double N = std::numeric_limits<double>::infinity();
|
||||||
|
Point P;
|
||||||
|
for (auto& intersection : intersections) {
|
||||||
|
if (boost::get<Point>(&(intersection->first))) {
|
||||||
|
const Point* p = boost::get<Point>(&(intersection->first));
|
||||||
|
const double d = std::sqrt(CGAL::to_double((*p - O).squared_length()));
|
||||||
|
if (d > 1.e-20 && d < N) {
|
||||||
|
N = d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (N != std::numeric_limits<double>::infinity() && N > 1.e-4) {
|
||||||
|
thin_sides.insert(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
Ray_intersection intersection = tree.first_intersection(ray, [f](const cgal_shape_t::Facet_handle& p) {
|
Ray_intersection intersection = tree.first_intersection(ray, [f](const cgal_shape_t::Facet_handle& p) {
|
||||||
return p == f;
|
return p == f;
|
||||||
});
|
});
|
||||||
@@ -1634,6 +1657,7 @@ namespace {
|
|||||||
} else {
|
} else {
|
||||||
std::wcout << "No intersection :((!!!" << std::endl;
|
std::wcout << "No intersection :((!!!" << std::endl;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
std::wcout << "THIN SIDES:" << std::endl;
|
std::wcout << "THIN SIDES:" << std::endl;
|
||||||
@@ -1652,6 +1676,8 @@ namespace {
|
|||||||
dump_facet(f);
|
dump_facet(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::wcout << "faces " << faces(polyhedron).size() << "long " << longitudonal.size() << "thin " << thin_sides.size() << "non-degen " << non_degenerate.size() << std::endl;
|
||||||
|
|
||||||
cgal_shape_t enlarged_indiv_triangles;
|
cgal_shape_t enlarged_indiv_triangles;
|
||||||
Build_Offset<cgal_shape_t::HDS> bo2;
|
Build_Offset<cgal_shape_t::HDS> bo2;
|
||||||
bo2.input = longitudonal;
|
bo2.input = longitudonal;
|
||||||
@@ -1700,7 +1726,7 @@ namespace {
|
|||||||
|
|
||||||
for (auto& v : vertices(polyhedron)) {
|
for (auto& v : vertices(polyhedron)) {
|
||||||
auto O = v->point();
|
auto O = v->point();
|
||||||
|
|
||||||
Kernel_::Vector_3 norm;
|
Kernel_::Vector_3 norm;
|
||||||
Kernel_::Vector_3 accum;
|
Kernel_::Vector_3 accum;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
@@ -1751,6 +1777,7 @@ namespace {
|
|||||||
std::wcout << "count " << count << std::endl;
|
std::wcout << "count " << count << std::endl;
|
||||||
|
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
|
// part of only degenerate or only thin sides
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1761,6 +1788,7 @@ namespace {
|
|||||||
oss << O << " -> " << norm;
|
oss << O << " -> " << norm;
|
||||||
auto osss = oss.str();
|
auto osss = oss.str();
|
||||||
std::wcout << osss.c_str() << std::endl;
|
std::wcout << osss.c_str() << std::endl;
|
||||||
|
|
||||||
//// skip does not work anymore because we have offset the facets
|
//// skip does not work anymore because we have offset the facets
|
||||||
// auto skip = [this, &v](const cgal_shape_t::Facet_handle& p) {
|
// auto skip = [this, &v](const cgal_shape_t::Facet_handle& p) {
|
||||||
// CGAL::Face_around_target_circulator<cgal_shape_t> it(v->halfedge(), polyhedron), end(it);
|
// CGAL::Face_around_target_circulator<cgal_shape_t> it(v->halfedge(), polyhedron), end(it);
|
||||||
@@ -1771,10 +1799,14 @@ namespace {
|
|||||||
// } while (++it != end);
|
// } while (++it != end);
|
||||||
// return false;
|
// return false;
|
||||||
// };
|
// };
|
||||||
|
|
||||||
std::list<Ray_intersection> intersections;
|
std::list<Ray_intersection> intersections;
|
||||||
tree2.all_intersections(ray, std::back_inserter(intersections));
|
tree2.all_intersections(ray, std::back_inserter(intersections));
|
||||||
double N = std::numeric_limits<double>::infinity();
|
double N = std::numeric_limits<double>::infinity();
|
||||||
Point P;
|
Point P;
|
||||||
|
|
||||||
|
bool used_intersection = false;
|
||||||
|
|
||||||
if (intersections.size()) {
|
if (intersections.size()) {
|
||||||
for (auto& intersection : intersections) {
|
for (auto& intersection : intersections) {
|
||||||
if (boost::get<Point>(&(intersection->first))) {
|
if (boost::get<Point>(&(intersection->first))) {
|
||||||
@@ -1783,15 +1815,18 @@ namespace {
|
|||||||
if (d < N && d > 1.e-20) {
|
if (d < N && d > 1.e-20) {
|
||||||
N = d;
|
N = d;
|
||||||
P = *p;
|
P = *p;
|
||||||
|
std::wcout << "intersection @ " << d << std::endl;
|
||||||
}
|
}
|
||||||
std::wcout << "intersection @ " << d << std::endl;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::wcout << "-----------" << std::endl;
|
std::wcout << "-----------" << std::endl;
|
||||||
|
|
||||||
// average the new point
|
// average the new point
|
||||||
new_points[O] = CGAL::ORIGIN + (((O - CGAL::ORIGIN) + (P - CGAL::ORIGIN))) / 2;
|
new_points[O] = CGAL::ORIGIN + (((O - CGAL::ORIGIN) + (P - CGAL::ORIGIN))) / 2;
|
||||||
} else {
|
used_intersection = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!used_intersection) {
|
||||||
std::wcout << "no intersection :(" << std::endl;
|
std::wcout << "no intersection :(" << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1803,7 +1838,31 @@ namespace {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
auto connected = connected_faces(*longitudonal.begin(), thin_sides);
|
auto thin_sides_degenerate = thin_sides;
|
||||||
|
thin_sides_degenerate.insert(degenerate.begin(), degenerate.end());
|
||||||
|
|
||||||
|
// @todo choose connected / connected_opposing based on largest combined area of facets?
|
||||||
|
|
||||||
|
auto connected = connected_faces(*longitudonal.begin(), thin_sides_degenerate);
|
||||||
|
decltype(connected) connected_opposing;
|
||||||
|
|
||||||
|
for (auto& f : longitudonal) {
|
||||||
|
if (std::find(connected.begin(), connected.end(), f) == connected.end()) {
|
||||||
|
connected_opposing = connected_faces(f, thin_sides_degenerate);
|
||||||
|
|
||||||
|
std::set<cgal_shape_t::Facet_handle> longi(longitudonal.begin(), longitudonal.end());
|
||||||
|
std::set<cgal_shape_t::Facet_handle> both_sides(connected.begin(), connected.end());
|
||||||
|
both_sides.insert(connected_opposing.begin(), connected_opposing.end());
|
||||||
|
|
||||||
|
if (longi == both_sides) {
|
||||||
|
std::wcout << "Facet connection functioning properly" << std::endl;
|
||||||
|
} else {
|
||||||
|
std::wcout << "Facet connection functioning incorrectly" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Builder_With_Map<cgal_shape_t::HDS> b2;
|
Builder_With_Map<cgal_shape_t::HDS> b2;
|
||||||
b2.input = connected;
|
b2.input = connected;
|
||||||
|
|||||||
Reference in New Issue
Block a user