mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-21 14:23:53 +00:00
Arrange polies: reorder segment to exterior insertion based on length
This commit is contained in:
@@ -1469,6 +1469,7 @@ std::vector<MergedBoxRecord> merge_intersecting_parallel_boxes_iterative(const s
|
|||||||
std::vector<size_t> members = clusters[i].members;
|
std::vector<size_t> members = clusters[i].members;
|
||||||
members.insert(members.end(), clusters[j].members.begin(), clusters[j].members.end());
|
members.insert(members.end(), clusters[j].members.begin(), clusters[j].members.end());
|
||||||
auto merged = BoxCluster{members, merge_cluster_to_box(members, records)};
|
auto merged = BoxCluster{members, merge_cluster_to_box(members, records)};
|
||||||
|
std::cout << "Result width: " << merged.box.avg_width << " fromt " << clusters[i].box.avg_width << " & " << clusters[j].box.avg_width << std::endl;
|
||||||
|
|
||||||
std::vector<BoxCluster> next_clusters;
|
std::vector<BoxCluster> next_clusters;
|
||||||
next_clusters.reserve(clusters.size() - 1);
|
next_clusters.reserve(clusters.size() - 1);
|
||||||
@@ -2170,92 +2171,115 @@ extend_end_vertices_based_on_input_simple(
|
|||||||
const K::FT& max_projection_distance)
|
const K::FT& max_projection_distance)
|
||||||
{
|
{
|
||||||
auto max_intersection_distance = max_projection_distance / 4;
|
auto max_intersection_distance = max_projection_distance / 4;
|
||||||
std::list<std::pair<Point_2, Point_2>> constructed_segments;
|
|
||||||
|
|
||||||
for (auto it = G.vertices_begin(); it != G.vertices_end(); ++it) {
|
const auto& process_point = [&](const Point_2& M, const Point_2& incoming) {
|
||||||
if (it->second.size() == 1) {
|
for (auto& bnd : outer_perimiter) {
|
||||||
auto& M = it->first;
|
// if point M is contained in bnd interior:
|
||||||
|
// if (!bnd.has_on_unbounded_side(M)) {
|
||||||
|
if (bnd.has_on_bounded_side(M)) {
|
||||||
|
// create ray incoming -> M
|
||||||
|
CGAL::Ray_2<K> ray(incoming, M - incoming);
|
||||||
|
|
||||||
for (auto& bnd : outer_perimiter) {
|
// intersect ray with boundary
|
||||||
// if point M is contained in bnd interior:
|
boost::optional<CGAL::Segment_2<K>> closest_segment;
|
||||||
// if (!bnd.has_on_unbounded_side(M)) {
|
boost::optional<CGAL::Point_2<K>> closest_intersection_point;
|
||||||
if (bnd.has_on_bounded_side(M)) {
|
K::FT sq_distance_along_ray = std::numeric_limits<double>::infinity();
|
||||||
auto& incoming = *it->second.begin();
|
for (auto jt = bnd.edges_begin(); jt != bnd.edges_end(); ++jt) {
|
||||||
// create ray incoming -> M
|
const auto& seg = *jt;
|
||||||
CGAL::Ray_2<K> ray(incoming, M - incoming);
|
auto x = CGAL::intersection(ray, seg);
|
||||||
|
if (x) {
|
||||||
|
if (auto* xp = variant_get<CGAL::Point_2<K>>(&*x)) {
|
||||||
|
auto dist = ((*xp) - M).squared_length();
|
||||||
|
if (dist < sq_distance_along_ray) {
|
||||||
|
if (dist < (max_intersection_distance * max_intersection_distance)) {
|
||||||
|
closest_segment = seg;
|
||||||
|
closest_intersection_point = *xp;
|
||||||
|
sq_distance_along_ray = dist;
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// intersect ray with boundary
|
if (closest_intersection_point) {
|
||||||
boost::optional<CGAL::Segment_2<K>> closest_segment;
|
return closest_intersection_point;
|
||||||
boost::optional<CGAL::Point_2<K>> closest_intersection_point;
|
// constructed_segments.push_front({M, *closest_intersection_point});
|
||||||
K::FT sq_distance_along_ray = std::numeric_limits<double>::infinity();
|
} else {
|
||||||
for (auto jt = bnd.edges_begin(); jt != bnd.edges_end(); ++jt) {
|
|
||||||
const auto& seg = *jt;
|
// Loop over boundary segments, and project point onto it, take the closest
|
||||||
auto x = CGAL::intersection(ray, seg);
|
K::FT closest_distance = std::numeric_limits<double>::infinity();
|
||||||
if (x) {
|
boost::optional<CGAL::Point_2<K>> closest_point;
|
||||||
if (auto* xp = variant_get<CGAL::Point_2<K>>(&*x)) {
|
for (auto& poly : outer_perimiter) {
|
||||||
auto dist = ((*xp) - M).squared_length();
|
for (auto jt = poly.edges_begin(); jt != poly.edges_end(); ++jt) {
|
||||||
if (dist < sq_distance_along_ray) {
|
auto seg = *jt;
|
||||||
if (dist < (max_intersection_distance * max_intersection_distance)) {
|
auto Pp = seg.supporting_line().projection(M);
|
||||||
closest_segment = seg;
|
if (seg.has_on(Pp)) {
|
||||||
closest_intersection_point = *xp;
|
auto d = CGAL::squared_distance(Pp, M);
|
||||||
sq_distance_along_ray = dist;
|
if (d < (max_projection_distance * max_projection_distance)) {
|
||||||
} else {
|
if (d < closest_distance) {
|
||||||
|
closest_distance = d;
|
||||||
|
closest_point = Pp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (closest_intersection_point) {
|
if (closest_point) {
|
||||||
constructed_segments.push_front({M, *closest_intersection_point});
|
return closest_point;
|
||||||
|
// constructed_segments.push_front({M, *closest_point});
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// Loop over boundary segments, and project point onto it, take the closest
|
|
||||||
K::FT closest_distance = std::numeric_limits<double>::infinity();
|
|
||||||
boost::optional<CGAL::Point_2<K>> closest_point;
|
|
||||||
for (auto& poly : outer_perimiter) {
|
for (auto& poly : outer_perimiter) {
|
||||||
for (auto jt = poly.edges_begin(); jt != poly.edges_end(); ++jt) {
|
for (auto it = poly.begin(); it != poly.end(); ++it) {
|
||||||
auto seg = *jt;
|
auto Pp = *it;
|
||||||
auto Pp = seg.supporting_line().projection(M);
|
auto d = CGAL::squared_distance(Pp, M);
|
||||||
if (seg.has_on(Pp)) {
|
if (d < (max_projection_distance * max_projection_distance)) {
|
||||||
auto d = CGAL::squared_distance(Pp, M);
|
if (d < closest_distance) {
|
||||||
if (d < (max_projection_distance * max_projection_distance)) {
|
closest_distance = d;
|
||||||
if (d < closest_distance) {
|
closest_point = Pp;
|
||||||
closest_distance = d;
|
|
||||||
closest_point = Pp;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (closest_point) {
|
if (closest_point) {
|
||||||
constructed_segments.push_front({M, *closest_point});
|
return closest_point;
|
||||||
|
// constructed_segments.push_front({M, *closest_point});
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
for (auto& poly : outer_perimiter) {
|
|
||||||
for (auto it = poly.begin(); it != poly.end(); ++it) {
|
|
||||||
auto Pp = *it;
|
|
||||||
auto d = CGAL::squared_distance(Pp, M);
|
|
||||||
if (d < (max_projection_distance * max_projection_distance)) {
|
|
||||||
if (d < closest_distance) {
|
|
||||||
closest_distance = d;
|
|
||||||
closest_point = Pp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (closest_point) {
|
|
||||||
constructed_segments.push_front({M, *closest_point});
|
|
||||||
} else {
|
|
||||||
std::cout << "Unable to find projection or intersection point for interior boundary (" << M.x() << " " << M.y() << ")" << std::endl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return boost::optional<Point_2>{};
|
||||||
|
};
|
||||||
|
|
||||||
|
using solution_length_point_incoming = std::tuple<K::FT, Point_2, Point_2>;
|
||||||
|
std::vector<solution_length_point_incoming> solutions;
|
||||||
|
|
||||||
|
for (auto it = G.vertices_begin(); it != G.vertices_end(); ++it) {
|
||||||
|
if (it->second.size() == 1) {
|
||||||
|
auto& M = it->first;
|
||||||
|
if (auto result = process_point(M, *it->second.begin())) {
|
||||||
|
auto d = (M - *result).squared_length();
|
||||||
|
solutions.emplace_back(d, *result, *it->second.begin());
|
||||||
|
} else {
|
||||||
|
std::cout << "Unable to find projection or intersection point for interior boundary (" << M.x() << " " << M.y() << ")" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::sort(solutions.begin(), solutions.end());
|
||||||
|
std::list<std::pair<Point_2, Point_2>> constructed_segments;
|
||||||
|
|
||||||
|
for (auto& [d, point, incoming] : solutions) {
|
||||||
|
if (auto result = process_point(point, incoming)) {
|
||||||
|
constructed_segments.push_front({point, *result});
|
||||||
|
} else {
|
||||||
|
std::cout << "Unable to find projection or intersection point for interior boundary (" << M.x() << " " << M.y() << ")" << std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return constructed_segments;
|
return constructed_segments;
|
||||||
|
|||||||
Reference in New Issue
Block a user