Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CURA-11444] Use 'wagyu' to prevent slicing crashes #2030

Merged
merged 11 commits into from
Feb 21, 2024
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ if (ENABLE_ARCUS)
target_link_libraries(_CuraEngine PUBLIC arcus::arcus)
endif ()

find_package(mapbox-wagyu REQUIRED)
find_package(clipper REQUIRED)
find_package(RapidJSON REQUIRED)
find_package(stb REQUIRED)
Expand All @@ -219,6 +220,7 @@ target_link_libraries(_CuraEngine
range-v3::range-v3
fmt::fmt
clipper::clipper
mapbox-wagyu::mapbox-wagyu
rapidjson
stb::stb
boost::boost
Expand Down Expand Up @@ -291,6 +293,7 @@ if (ENABLE_TESTING OR ENABLE_BENCHMARKS)
GTest::gtest
GTest::gmock
clipper::clipper
mapbox-wagyu::mapbox-wagyu
$<$<TARGET_EXISTS:curaengine_grpc_definitions::curaengine_grpc_definitions>:curaengine_grpc_definitions::curaengine_grpc_definitions>
$<$<TARGET_EXISTS:asio-grpc::asio-grpc>:asio-grpc::asio-grpc>
$<$<TARGET_EXISTS:grpc::grpc>:grpc::grpc>
Expand Down
1 change: 1 addition & 0 deletions conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ def requirements(self):
self.requires("range-v3/0.12.0")
self.requires("zlib/1.2.12")
self.requires("openssl/3.2.0")
self.requires("mapbox-wagyu/0.5.0@ultimaker/stable")

def generate(self):
deps = CMakeDeps(self)
Expand Down
13 changes: 12 additions & 1 deletion include/utils/polygon.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2023 UltiMaker
// Copyright (c) 2024 UltiMaker
// CuraEngine is released under the terms of the AGPLv3 or higher

#ifndef UTILS_POLYGON_H
Expand Down Expand Up @@ -1536,6 +1536,17 @@ class Polygons
* @return Polygons The polygons read from the stream
*/
[[maybe_unused]] static Polygons fromWkt(const std::string& wkt);

/*!
* @brief Remove self-intersections from the polygons
* _note_: this function uses wagyu to remove the self intersections.
* since wagyu uses a different internal representation of the polygons
* we need to convert back and forward between data structures which
* might impact performance, use wisely!
*
* @return Polygons - the cleaned polygons
*/
Polygons removeNearSelfIntersections() const;
};

/*!
Expand Down
2 changes: 1 addition & 1 deletion src/FffGcodeWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1443,7 +1443,7 @@ void FffGcodeWriter::processSkirtBrim(const SliceDataStorage& storage, LayerPlan
start_close_to,
fan_speed,
reverse_print_direction,
order_requirements);
layer_nr == 0 ? order_requirements : PathOrderOptimizer<ConstPolygonPointer>::no_order_requirements_);
}


Expand Down
2 changes: 2 additions & 0 deletions src/WallToolPaths.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ const std::vector<VariableWidthLines>& WallToolPaths::generate()
return toolpaths_;
}

prepared_outline = prepared_outline.removeNearSelfIntersections();

const coord_t wall_transition_length = settings_.get<coord_t>("wall_transition_length");

// When to split the middle wall into two:
Expand Down
53 changes: 53 additions & 0 deletions src/utils/polygon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include "utils/polygon.h"

#include <mapbox/geometry/wagyu/wagyu.hpp>
#include <unordered_set>

#include <boost/geometry/geometries/point_xy.hpp>
Expand Down Expand Up @@ -1582,6 +1583,58 @@ Polygons Polygons::tubeShape(const coord_t inner_offset, const coord_t outer_off
return this->offset(outer_offset).difference(this->offset(-inner_offset));
}

Polygons Polygons::removeNearSelfIntersections() const
{
using map_pt = mapbox::geometry::point<coord_t>;
using map_ring = mapbox::geometry::linear_ring<coord_t>;
using map_poly = mapbox::geometry::polygon<coord_t>;
using map_mpoly = mapbox::geometry::multi_polygon<coord_t>;

map_mpoly mwpoly;

mapbox::geometry::wagyu::wagyu<coord_t> wagyu;

for (auto& polygon : splitIntoParts())
{
mwpoly.emplace_back();
map_poly& wpoly = mwpoly.back();
for (auto& path : polygon)
{
wpoly.push_back(std::move(*reinterpret_cast<std::vector<mapbox::geometry::point<coord_t>>*>(&path)));
for (auto& point : wpoly.back())
{
point.x /= 4;
point.y /= 4;
}
wagyu.add_ring(wpoly.back());
}
}

map_mpoly sln;

wagyu.execute(mapbox::geometry::wagyu::clip_type_union, sln, mapbox::geometry::wagyu::fill_type_even_odd, mapbox::geometry::wagyu::fill_type_even_odd);

Polygons polys;

for (auto& poly : sln)
{
for (auto& ring : poly)
{
ring.pop_back();
for (auto& point : ring)
{
point.x *= 4;
point.y *= 4;
}
polys.add(*reinterpret_cast<std::vector<ClipperLib::IntPoint>*>(&ring)); // NOTE: 'add' already moves the vector
}
}
polys = polys.unionPolygons();
polys.removeColinearEdges();

return polys;
}

size_t PartsView::getPartContaining(size_t poly_idx, size_t* boundary_poly_idx) const
{
const PartsView& partsView = *this;
Expand Down
Loading