| 562 | } |
| 563 | |
| 564 | void pathObjectToPolygons( |
| 565 | const PathObject* object, |
| 566 | ClipperLib::Paths& polygons, |
| 567 | PolyMap& polymap) |
| 568 | { |
| 569 | object->update(); |
| 570 | auto coords = object->getRawCoordinateVector(); |
| 571 | |
| 572 | polygons.reserve(polygons.size() + object->parts().size()); |
| 573 | |
| 574 | for (const auto& part : object->parts()) |
| 575 | { |
| 576 | const PathCoordVector& path_coords = part.path_coords; |
| 577 | auto path_coords_end = path_coords.size(); |
| 578 | if (part.isClosed()) |
| 579 | --path_coords_end; |
| 580 | |
| 581 | ClipperLib::Path polygon; |
| 582 | polygon.reserve(path_coords_end); |
| 583 | for (auto i = 0u; i < path_coords_end; ++i) |
| 584 | { |
| 585 | auto& path_coord = path_coords[i]; |
| 586 | if (path_coord.param == 0.0) |
| 587 | { |
| 588 | auto point = coords[path_coord.index]; |
| 589 | polygon.push_back(ClipperLib::IntPoint(point.nativeX(), point.nativeY())); |
| 590 | } |
| 591 | else |
| 592 | { |
| 593 | auto point = MapCoord { path_coord.pos }; |
| 594 | polygon.push_back(ClipperLib::IntPoint(point.nativeX(), point.nativeY())); |
| 595 | } |
| 596 | polymap.insertMulti(polygon.back(), std::make_pair(&part, &path_coord)); |
| 597 | } |
| 598 | |
| 599 | bool orientation = Orientation(polygon); |
| 600 | if ( (&part == &object->parts().front()) != orientation ) |
| 601 | { |
| 602 | std::reverse(polygon.begin(), polygon.end()); |
| 603 | } |
| 604 | |
| 605 | // Push_back shall move the polygon. |
| 606 | static_assert(std::is_nothrow_move_constructible<ClipperLib::Path>::value, "ClipperLib::Path must be nothrow move constructible"); |
| 607 | polygons.push_back(polygon); |
| 608 | } |
| 609 | } |
| 610 | |
| 611 | void polygonToPathPart(const ClipperLib::Path& polygon, const PolyMap& polymap, PathObject* object) |
| 612 | { |
no test coverage detected