mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-06-04 11:14:17 +08:00
151 lines
5.6 KiB
C++
151 lines
5.6 KiB
C++
#include "libslic3r/ClipperUtils.hpp"
|
|
#include "libslic3r/Geometry.hpp"
|
|
#include "libslic3r/Point.hpp"
|
|
#include "libslic3r/SVG.hpp"
|
|
#include <catch2/catch_test_macros.hpp>
|
|
#include <catch2/catch_approx.hpp>
|
|
#include <libslic3r/LayerRegion.hpp>
|
|
|
|
using namespace Slic3r;
|
|
using namespace Slic3r::Algorithm;
|
|
using namespace Catch;
|
|
|
|
constexpr bool export_svgs = false;
|
|
|
|
ExPolygon rectangle(const Point& origin, const int width, const int height) {
|
|
return {
|
|
origin,
|
|
origin + Point{width, 0},
|
|
origin + Point{width, height},
|
|
origin + Point{0, height},
|
|
};
|
|
}
|
|
|
|
struct LayerRegionFixture {
|
|
Surfaces surfaces{
|
|
Surface{
|
|
stBottomBridge,
|
|
rectangle({scaled(-1.0), scaled(0.0)}, scaled(1.0), scaled(1.0))
|
|
},
|
|
Surface{
|
|
stBottomBridge,
|
|
rectangle({scaled(0.0), scaled(0.0)}, scaled(1.0), scaled(1.0))
|
|
},
|
|
Surface{
|
|
stBottomBridge,
|
|
rectangle({scaled(-3.0), scaled(0.0)}, scaled(1.0), scaled(1.0))
|
|
}
|
|
};
|
|
|
|
ExPolygons shells{{
|
|
rectangle({scaled(-1.0), scaled(1.0)}, scaled(3.0), scaled(1.0))
|
|
}};
|
|
ExPolygons sparse {{
|
|
rectangle({scaled(-2.0), scaled(-1.0)}, scaled(1.0), scaled(3.0))
|
|
}};
|
|
|
|
const float scaled_spacing{scaled(0.3)};
|
|
|
|
static constexpr const float expansion_step = scaled<float>(0.1);
|
|
static constexpr const size_t max_nr_expansion_steps = 5;
|
|
const float closing_radius = 0.55f * 0.65f * 1.05f * scaled_spacing;
|
|
const int shells_expansion_depth = scaled(0.6);
|
|
const RegionExpansionParameters expansion_params_into_solid_infill = RegionExpansionParameters::build(
|
|
shells_expansion_depth,
|
|
expansion_step,
|
|
max_nr_expansion_steps
|
|
);
|
|
const int sparse_expansion_depth = scaled(0.3);
|
|
const RegionExpansionParameters expansion_params_into_sparse_infill = RegionExpansionParameters::build(
|
|
sparse_expansion_depth,
|
|
expansion_step,
|
|
max_nr_expansion_steps
|
|
);
|
|
|
|
std::vector<ExpansionZone> expansion_zones{
|
|
ExpansionZone{
|
|
std::move(shells),
|
|
expansion_params_into_solid_infill,
|
|
},
|
|
ExpansionZone{
|
|
std::move(sparse),
|
|
expansion_params_into_sparse_infill,
|
|
}
|
|
};
|
|
};
|
|
|
|
TEST_CASE_METHOD(LayerRegionFixture, "test the surface expansion", "[LayerRegion]") {
|
|
const double custom_angle{1.234f};
|
|
|
|
const Surfaces result{expand_merge_surfaces(
|
|
surfaces, stBottomBridge,
|
|
expansion_zones,
|
|
closing_radius,
|
|
custom_angle
|
|
)};
|
|
|
|
if constexpr (export_svgs) {
|
|
SVG svg("general_expansion.svg", BoundingBox{
|
|
Point{scaled(-3.0), scaled(-1.0)},
|
|
Point{scaled(2.0), scaled(2.0)}
|
|
});
|
|
|
|
svg.draw(surfaces, "blue");
|
|
svg.draw(expansion_zones[0].expolygons, "green");
|
|
svg.draw(expansion_zones[1].expolygons, "red");
|
|
svg.draw_outline(result, "black", "", scale_(0.01));
|
|
}
|
|
|
|
REQUIRE(result.size() == 2);
|
|
CHECK(result.at(0).bridge_angle == Approx(custom_angle));
|
|
CHECK(result.at(1).bridge_angle == Approx(custom_angle));
|
|
CHECK(result.at(0).expolygon.contour.size() == 22);
|
|
CHECK(result.at(1).expolygon.contour.size() == 14);
|
|
|
|
// These lines in the polygons should correspond to the expansion depth.
|
|
CHECK(result.at(0).expolygon.contour.lines().at(2).length() == shells_expansion_depth);
|
|
CHECK(result.at(1).expolygon.contour.lines().at(7).length() == sparse_expansion_depth);
|
|
CHECK(result.at(1).expolygon.contour.lines().at(11).length() == sparse_expansion_depth);
|
|
|
|
CHECK(intersection_ex({result.at(0).expolygon}, expansion_zones[0].expolygons).size() == 0);
|
|
CHECK(intersection_ex({result.at(0).expolygon}, expansion_zones[1].expolygons).size() == 0);
|
|
CHECK(intersection_ex({result.at(1).expolygon}, expansion_zones[0].expolygons).size() == 0);
|
|
CHECK(intersection_ex({result.at(1).expolygon}, expansion_zones[1].expolygons).size() == 0);
|
|
}
|
|
|
|
TEST_CASE_METHOD(LayerRegionFixture, "test the bridge expansion with the bridge angle detection", "[LayerRegion]") {
|
|
Surfaces result{expand_bridges_detect_orientations(
|
|
surfaces,
|
|
expansion_zones,
|
|
closing_radius
|
|
)};
|
|
|
|
if constexpr (export_svgs) {
|
|
SVG svg("bridge_expansion.svg", BoundingBox{
|
|
Point{scaled(-3.0), scaled(-1.0)},
|
|
Point{scaled(2.0), scaled(2.0)}
|
|
});
|
|
|
|
svg.draw(surfaces, "blue");
|
|
svg.draw(expansion_zones[0].expolygons, "green");
|
|
svg.draw(expansion_zones[1].expolygons, "red");
|
|
svg.draw_outline(result, "black", "", scale_(0.01));
|
|
}
|
|
|
|
REQUIRE(result.size() == 2);
|
|
CHECK(std::fmod(result.at(1).bridge_angle, M_PI) == Approx(0.0));
|
|
CHECK(std::fmod(result.at(1).bridge_angle, M_PI) == Approx(0.0));
|
|
CHECK(result.at(0).expolygon.contour.size() == 22);
|
|
CHECK(result.at(1).expolygon.contour.size() == 14);
|
|
|
|
// These lines in the polygons should correspond to the expansion depth.
|
|
CHECK(result.at(0).expolygon.contour.lines().at(2).length() == shells_expansion_depth);
|
|
CHECK(result.at(1).expolygon.contour.lines().at(7).length() == sparse_expansion_depth);
|
|
CHECK(result.at(1).expolygon.contour.lines().at(11).length() == sparse_expansion_depth);
|
|
|
|
CHECK(intersection_ex({result.at(0).expolygon}, expansion_zones[0].expolygons).size() == 0);
|
|
CHECK(intersection_ex({result.at(0).expolygon}, expansion_zones[1].expolygons).size() == 0);
|
|
CHECK(intersection_ex({result.at(1).expolygon}, expansion_zones[0].expolygons).size() == 0);
|
|
CHECK(intersection_ex({result.at(1).expolygon}, expansion_zones[1].expolygons).size() == 0);
|
|
}
|