Re-enable remove_duplicate_points_from_loop

This commit is contained in:
Thomas Krijnen
2024-12-10 21:30:43 +01:00
parent ab17c8ffd9
commit 139b83ea0c
4 changed files with 47 additions and 25 deletions
+5 -21
View File
@@ -42,7 +42,11 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcPolyLoop* inst) {
// @todo Remove points that are too close to one another
const double eps = settings_.get<settings::Precision>().get();
// util::remove_duplicate_points_from_loop(polygon, true, eps);
auto previous_size = polygon.size();
remove_duplicate_points_from_loop(polygon, true, eps);
if (polygon.size() != previous_size) {
Logger::Warning("Removed " + std::to_string(previous_size - polygon.size()) + " (near) duplicate points from:", inst);
}
int count = polygon.size();
if (original_count - count != 0) {
@@ -59,24 +63,4 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcPolyLoop* inst) {
polygon.push_back(polygon.front());
return polygon_from_points(polygon);
// @todo make sure wire intersection check happens
/*
BRepBuilderAPI_MakePolygon w;
for (int i = 1; i <= polygon.Length(); ++i) {
w.Add(polygon.Value(i));
}
w.Close();
result = w.Wire();
TopTools_ListOfShape results;
if (getValue(GV_NO_WIRE_INTERSECTION_CHECK) < 0. && util::wire_intersections(result, results, {getValue(GV_NO_WIRE_INTERSECTION_CHECK) < 0., getValue(GV_NO_WIRE_INTERSECTION_TOLERANCE) < 0., 0., getValue(GV_PRECISION)})) {
Logger::Error("Self-intersections with " + boost::lexical_cast<std::string>(results.Extent()) + " cycles detected", l);
util::select_largest(results, result);
}
return true;
*/
}
+14 -4
View File
@@ -33,19 +33,29 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcPolyline* inst) {
return taxonomy::cast<taxonomy::point3>(map(p));
});
const bool closed_by_proximity = polygon.size() >= 3 && (*polygon.front()->components_ - *polygon.back()->components_).norm() < settings_.get<settings::Precision>().get();
auto eps = this->settings_.get<settings::Precision>().get();
const bool closed_by_proximity = polygon.size() >= 3 && (polygon.front()->ccomponents() - polygon.back()->ccomponents()).norm() < eps;
if (closed_by_proximity) {
polygon.resize(polygon.size() - 1);
polygon.push_back(polygon.front());
}
// @todo Remove points that are too close to one another
// util::remove_duplicate_points_from_loop(polygon, closed_by_proximity, eps);
// Remove points that are too close to one another
auto previous_size = polygon.size();
remove_duplicate_points_from_loop(polygon, closed_by_proximity, eps);
if (polygon.size() != previous_size) {
Logger::Warning("Removed " + std::to_string(previous_size - polygon.size()) + " (near) duplicate points from:", inst);
}
if (polygon.size() < 2) {
// We somehow need to signal we fail this curve on purpose not to trigger an error.
Logger::Warning("Invalid polyline with " + std::to_string(polygon.size()) + " points:", inst);
return nullptr;
}
if (closed_by_proximity) {
polygon.push_back(polygon.front());
}
return polygon_from_points(polygon);
}
+26
View File
@@ -54,6 +54,32 @@ taxonomy::loop::ptr ifcopenshell::geometry::fillet_loop(taxonomy::loop::ptr loop
return loop;
}
void ifcopenshell::geometry::remove_duplicate_points_from_loop(std::vector<taxonomy::point3::ptr>& polygon, bool closed, double tol) {
tol *= tol;
for (;;) {
bool removed = false;
int n = polygon.size() - (closed ? 0 : 1);
for (size_t i = 0; i < n; ++i) {
// wrap around to the first point in case of a closed loop
auto j = (i + 1) % polygon.size();
double dist = (polygon[i]->ccomponents() - polygon[j]->ccomponents()).squaredNorm();
if (dist < tol) {
// do not remove the first or last point to
// maintain connectivity with other wires
if ((closed && j == 0) || (!closed && j == (n - 1))) {
polygon.erase(polygon.begin() + i);
} else {
polygon.erase(polygon.begin() + j);
}
removed = true;
break;
}
}
if (!removed) break;
}
}
taxonomy::loop::ptr ifcopenshell::geometry::polygon_from_points(const std::vector<taxonomy::point3::ptr>& ps, bool external) {
auto loop = taxonomy::make<taxonomy::loop>();
loop->external = external;
+2
View File
@@ -28,6 +28,8 @@ namespace ifcopenshell {
taxonomy::loop::ptr profile_helper(const taxonomy::matrix4::ptr& m4, const std::vector<profile_point>& points);
taxonomy::loop::ptr fillet_loop(taxonomy::loop::ptr lp, double radius);
void remove_duplicate_points_from_loop(std::vector<taxonomy::point3::ptr>& polygon, bool closed, double tol);
}
}