diff --git a/src/libslic3r/SupportSpotsGenerator.cpp b/src/libslic3r/SupportSpotsGenerator.cpp index e9841fe1e2..4d531900b4 100644 --- a/src/libslic3r/SupportSpotsGenerator.cpp +++ b/src/libslic3r/SupportSpotsGenerator.cpp @@ -478,11 +478,11 @@ ObjectPart::ObjectPart( const Integrals integrals{polygons}; const float volume = integrals.area * layer_height; this->volume += volume; - this->volume_centroid_accumulator += to_3d(integrals.x_i, center_z * integrals.area) / integrals.area * volume; // TODO check that it is correct + this->volume_centroid_accumulator += to_3d(integrals.x_i, center_z * integrals.area) / integrals.area * volume; if (this->connected_to_bed) { this->sticking_area += integrals.area; - this->sticking_centroid_accumulator += to_3d(integrals.x_i, bottom_z * integrals.area); // TODO check that it layer height should be added + this->sticking_centroid_accumulator += to_3d(integrals.x_i, bottom_z * integrals.area); this->sticking_second_moment_of_area_accumulator += integrals.x_i_squared; this->sticking_second_moment_of_area_covariance_accumulator += integrals.xy; } diff --git a/src/libslic3r/SupportSpotsGenerator.hpp b/src/libslic3r/SupportSpotsGenerator.hpp index 1b35f718ea..62f4e960d4 100644 --- a/src/libslic3r/SupportSpotsGenerator.hpp +++ b/src/libslic3r/SupportSpotsGenerator.hpp @@ -208,6 +208,8 @@ struct SliceConnection void print_info(const std::string &tag) const; }; +Polygons get_brim(const ExPolygon& slice_polygon, const BrimType brim_type, const float brim_width); + class ObjectPart { public: diff --git a/tests/libslic3r/test_support_spots_generator.cpp b/tests/libslic3r/test_support_spots_generator.cpp index 19d7e4b0c5..d7b2f4611c 100644 --- a/tests/libslic3r/test_support_spots_generator.cpp +++ b/tests/libslic3r/test_support_spots_generator.cpp @@ -96,23 +96,70 @@ TEST_CASE("Moments calculation for rotated axis.", "[SupportSpotsGenerator]") { CHECK(moment_calculated_then_rotated == Approx(moment_rotated_polygon)); } -TEST_CASE("TODO", "[SupportSpotsGenerator]") { +struct ObjectPartFixture { const Polyline polyline{ Point{scaled(Vec2f{0, 0})}, Point{scaled(Vec2f{1, 0})}, }; + const float width = 0.1f; + bool connected_to_bed = true; + coordf_t print_head_z = 0.2; + coordf_t layer_height = 0.2; ExtrusionAttributes attributes; - attributes.width = 0.1; - const ExtrusionPath path{polyline, attributes}; ExtrusionEntityCollection collection; - collection.append(path); - std::vector collections{&collection}; + std::vector extrusions{}; + Polygon expected_polygon{ + Point{scaled(Vec2f{0, -width / 2})}, + Point{scaled(Vec2f{1, -width / 2})}, + Point{scaled(Vec2f{1, width / 2})}, + Point{scaled(Vec2f{0, width / 2})} + }; - Polygons polygons = path.polygons_covered_by_width(); - for (const Polygon& polygon : polygons) { - std::cout << "Polygon: " << std::endl; - for (const Line& line : polygon.lines()) { - std::cout << "(" << line.a.x() << ", " << line.a.y() << ")" << std::endl; - } + ObjectPartFixture() { + attributes.width = width; + const ExtrusionPath path{polyline, attributes}; + collection.append(path); + extrusions.push_back(&collection); } +}; + +TEST_CASE_METHOD(ObjectPartFixture, "Constructing ObjectPart using extrusion collections", "[SupportSpotsGenerator]") { + ObjectPart part{ + extrusions, + connected_to_bed, + print_head_z, + layer_height, + std::nullopt + }; + + Integrals expected{{expected_polygon}}; + + CHECK(part.connected_to_bed == true); + Vec3f volume_centroid{part.volume_centroid_accumulator / part.volume}; + CHECK(volume_centroid.x() == Approx(0.5)); + CHECK(volume_centroid.y() == Approx(0)); + CHECK(volume_centroid.z() == Approx(layer_height / 2)); + CHECK(part.sticking_area == Approx(expected.area)); + CHECK(part.sticking_centroid_accumulator.x() == Approx(expected.x_i.x())); + CHECK(part.sticking_centroid_accumulator.y() == Approx(expected.x_i.y())); + CHECK(part.sticking_second_moment_of_area_accumulator.x() == Approx(expected.x_i_squared.x())); + CHECK(part.sticking_second_moment_of_area_accumulator.y() == Approx(expected.x_i_squared.y())); + CHECK(part.sticking_second_moment_of_area_covariance_accumulator == Approx(expected.xy).margin(1e-6)); + CHECK(part.volume == Approx(layer_height * width)); } + +TEST_CASE_METHOD(ObjectPartFixture, "Constructing ObjectPart with brim", "[SupportSpotsGenerator]") { + float brim_width = 1; + Polygons brim = get_brim(ExPolygon{expected_polygon}, BrimType::btOuterOnly, brim_width); + + ObjectPart part{ + extrusions, + connected_to_bed, + print_head_z, + layer_height, + brim + }; + + CHECK(part.sticking_area == Approx((1 + 2*brim_width) * (width + 2*brim_width))); +} +