Ported remove_collinear(Polygon) and test_polygon from upstream slic3r.
This commit is contained in:
parent
de45be5f29
commit
abe856f9fe
@ -1,7 +1,7 @@
|
||||
#ifndef slic3r_CoolingBuffer_hpp_
|
||||
#define slic3r_CoolingBuffer_hpp_
|
||||
|
||||
#include "libslic3r.h"
|
||||
#include "../libslic3r.h"
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
|
@ -15,7 +15,7 @@ Polyline Polygon::split_at_vertex(const Point &point) const
|
||||
// find index of point
|
||||
for (const Point &pt : this->points)
|
||||
if (pt == point)
|
||||
return this->split_at_index(&pt - &this->points.front());
|
||||
return this->split_at_index(int(&pt - &this->points.front()));
|
||||
throw std::invalid_argument("Point not found");
|
||||
return Polyline();
|
||||
}
|
||||
@ -394,4 +394,45 @@ bool remove_small(Polygons &polys, double min_area)
|
||||
return modified;
|
||||
}
|
||||
|
||||
void remove_collinear(Polygon &poly)
|
||||
{
|
||||
if (poly.points.size() > 2) {
|
||||
// copy points and append both 1 and last point in place to cover the boundaries
|
||||
Points pp;
|
||||
pp.reserve(poly.points.size()+2);
|
||||
pp.push_back(poly.points.back());
|
||||
pp.insert(pp.begin()+1, poly.points.begin(), poly.points.end());
|
||||
pp.push_back(poly.points.front());
|
||||
// delete old points vector. Will be re-filled in the loop
|
||||
poly.points.clear();
|
||||
|
||||
size_t i = 0;
|
||||
size_t k = 0;
|
||||
while (i < pp.size()-2) {
|
||||
k = i+1;
|
||||
const Point &p1 = pp[i];
|
||||
while (k < pp.size()-1) {
|
||||
const Point &p2 = pp[k];
|
||||
const Point &p3 = pp[k+1];
|
||||
Line l(p1, p3);
|
||||
if(l.distance_to(p2) < SCALED_EPSILON) {
|
||||
k++;
|
||||
} else {
|
||||
if(i > 0) poly.points.push_back(p1); // implicitly removes the first point we appended above
|
||||
i = k;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(k > pp.size()-2) break; // all remaining points are collinear and can be skipped
|
||||
}
|
||||
poly.points.push_back(pp[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void remove_collinear(Polygons &polys)
|
||||
{
|
||||
for (Polygon &poly : polys)
|
||||
remove_collinear(poly);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -86,6 +86,8 @@ extern bool remove_sticks(Polygons &polys);
|
||||
// Remove polygons with less than 3 edges.
|
||||
extern bool remove_degenerate(Polygons &polys);
|
||||
extern bool remove_small(Polygons &polys, double min_area);
|
||||
extern void remove_collinear(Polygon &poly);
|
||||
extern void remove_collinear(Polygons &polys);
|
||||
|
||||
// Append a vector of polygons at the end of another vector of polygons.
|
||||
inline void polygons_append(Polygons &dst, const Polygons &src) { dst.insert(dst.end(), src.begin(), src.end()); }
|
||||
|
@ -2,6 +2,7 @@ get_filename_component(_TEST_NAME ${CMAKE_CURRENT_LIST_DIR} NAME)
|
||||
add_executable(${_TEST_NAME}_tests
|
||||
${_TEST_NAME}_tests.cpp
|
||||
test_geometry.cpp
|
||||
test_polygon.cpp
|
||||
)
|
||||
target_link_libraries(${_TEST_NAME}_tests test_common libslic3r)
|
||||
set_property(TARGET ${_TEST_NAME}_tests PROPERTY FOLDER "tests")
|
||||
|
44
tests/libslic3r/test_polygon.cpp
Normal file
44
tests/libslic3r/test_polygon.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
#include <catch2/catch.hpp>
|
||||
|
||||
#include "libslic3r/Point.hpp"
|
||||
#include "libslic3r/Polygon.hpp"
|
||||
|
||||
using namespace Slic3r;
|
||||
|
||||
// This test currently only covers remove_collinear_points.
|
||||
// All remaining tests are to be ported from xs/t/06_polygon.t
|
||||
|
||||
Slic3r::Points collinear_circle({
|
||||
Slic3r::Point::new_scale(0, 0), // 3 collinear points at beginning
|
||||
Slic3r::Point::new_scale(10, 0),
|
||||
Slic3r::Point::new_scale(20, 0),
|
||||
Slic3r::Point::new_scale(30, 10),
|
||||
Slic3r::Point::new_scale(40, 20), // 2 collinear points
|
||||
Slic3r::Point::new_scale(40, 30),
|
||||
Slic3r::Point::new_scale(30, 40), // 3 collinear points
|
||||
Slic3r::Point::new_scale(20, 40),
|
||||
Slic3r::Point::new_scale(10, 40),
|
||||
Slic3r::Point::new_scale(-10, 20),
|
||||
Slic3r::Point::new_scale(-20, 10),
|
||||
Slic3r::Point::new_scale(-20, 0), // 3 collinear points at end
|
||||
Slic3r::Point::new_scale(-10, 0),
|
||||
Slic3r::Point::new_scale(-5, 0)
|
||||
});
|
||||
|
||||
SCENARIO("Remove collinear points from Polygon") {
|
||||
GIVEN("Polygon with collinear points"){
|
||||
Slic3r::Polygon p(collinear_circle);
|
||||
WHEN("collinear points are removed") {
|
||||
remove_collinear(p);
|
||||
THEN("Leading collinear points are removed") {
|
||||
REQUIRE(p.points.front() == Slic3r::Point::new_scale(20, 0));
|
||||
}
|
||||
THEN("Trailing collinear points are removed") {
|
||||
REQUIRE(p.points.back() == Slic3r::Point::new_scale(-20, 0));
|
||||
}
|
||||
THEN("Number of remaining points is correct") {
|
||||
REQUIRE(p.points.size() == 7);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user