| 24 | #include "../profile_helper.h" |
| 25 | |
| 26 | taxonomy::ptr mapping::map_impl(const IfcSchema::IfcPolyLoop* inst) { |
| 27 | IfcSchema::IfcCartesianPoint::list::ptr points = inst->Polygon(); |
| 28 | |
| 29 | // Parse and store the points in a sequence |
| 30 | std::vector<taxonomy::point3::ptr> polygon; |
| 31 | polygon.reserve(points->size()); |
| 32 | std::transform(points->begin(), points->end(), std::back_inserter(polygon), [this](const IfcSchema::IfcCartesianPoint* p) { |
| 33 | return taxonomy::cast<taxonomy::point3>(map(p)); |
| 34 | }); |
| 35 | |
| 36 | // A loop should consist of at least three vertices |
| 37 | int original_count = polygon.size(); |
| 38 | if (original_count < 3) { |
| 39 | Logger::Message(Logger::LOG_WARNING, "Not enough edges for:", inst); |
| 40 | return nullptr; |
| 41 | } |
| 42 | |
| 43 | // @todo Remove points that are too close to one another |
| 44 | const double eps = settings_.get<settings::Precision>().get(); |
| 45 | auto previous_size = polygon.size(); |
| 46 | remove_duplicate_points_from_loop(polygon, true, eps); |
| 47 | if (polygon.size() != previous_size) { |
| 48 | Logger::Warning("Removed " + std::to_string(previous_size - polygon.size()) + " (near) duplicate points from:", inst); |
| 49 | } |
| 50 | |
| 51 | int count = polygon.size(); |
| 52 | if (original_count - count != 0) { |
| 53 | std::stringstream ss; ss << (original_count - count) << " edges removed for:"; |
| 54 | Logger::Message(Logger::LOG_WARNING, ss.str(), inst); |
| 55 | } |
| 56 | |
| 57 | if (count < 3) { |
| 58 | Logger::Message(Logger::LOG_WARNING, "Not enough edges for:", inst); |
| 59 | return nullptr; |
| 60 | } |
| 61 | |
| 62 | // Contrary to polyline the loop is implicitly closed |
| 63 | polygon.push_back(polygon.front()); |
| 64 | |
| 65 | return polygon_from_points(polygon); |
| 66 | } |