Optimize FillTpmsFK using optimized MarchingSquares from #10747. (#10876)

# Change FillTpmsFK.cpp to use MarchingSquares.hpp.

This is still a work in progress, but it does seem to work fine, and I
thought I'd put this up there for people to have a play with. I also
have a few questions because I'm not 100% familiar with the rest of the
codebase and I'm going to use the review of this to figure a few things
out.

This builds on #10747 which simplified and significantly optimized
MarchingSquares.hpp by replacing most of FillTpmsFK.cpp's implementation
to just use that marching squares implementation instead of
re-implementing it's own.

I don't yet have any solid speed comparisons but it feels a bit
subjectively faster, though I think that most of the delay in previewing
the slicing results is not in the fill-generation so it's a bit hard to
tell. I don't know if there are any tests/benchmarks/etc that I could
use for testing this, but I'm probably going to add some to this PR at
some point.

Even if this doesn't give a significant speed-up, it does significantly
simplify the code and make it easier to re-use for other equation based
fill-patterns. This could re-implement gyroid or TpmsD with about 5
lines of C code to inherit from `ScalarField` and redefine the `float
get_scalar(coordf_t x, coordf_t y, coordf_t z)` function with the
appropriate equation.

I don't think it would be faster than the current gyroid or TpmsD fills
though, since they directly generate a single line using the equation
and then just copy and shift it. However, it might not be much slower
and it would simplify the code to do them all the same way.

But the main reason I'm doing this is this can be used to implement far
more complicated fills that can't really be implemented any other way.
In particular I'm working towards a gyroid fill that dynamically varies
it's density based on how close it is to the walls.

I have a bunch of questions about some of the other bits that I'll post
as comments against the review-diff.

# Screenshots/Recordings/Graphs

I'll add some when I get there... but so far the results look identical
to the previous implementation even when I zoom in close.

<!--
> Please attach relevant screenshots to showcase the UI changes.
> Please attach images that can help explain the changes.
-->

## Tests

<!--
> Please describe the tests that you have conducted to verify the
changes made in this PR.
-->
This commit is contained in:
Donovan Baarda
2025-10-25 14:17:43 +11:00
committed by GitHub
parent 339636b91f
commit f5bbe52ac9
2 changed files with 147 additions and 427 deletions

View File

@@ -2712,7 +2712,7 @@ void multiline_fill(Polylines& polylines, const FillParams& params, float spacin
const float center = (n_lines - 1) / 2.0f;
for (int line = 0; line < n_lines; ++line) {
float offset = (static_cast<float>(line) - center) * spacing;
float offset = scale_((static_cast<float>(line) - center) * spacing);
for (const Polyline& pl : polylines) {
const size_t n = pl.points.size();
@@ -2725,22 +2725,27 @@ void multiline_fill(Polylines& polylines, const FillParams& params, float spacin
new_points.reserve(n);
for (size_t i = 0; i < n; ++i) {
Vec2f tangent;
if (i == 0)
tangent = Vec2f(pl.points[1].x() - pl.points[0].x(), pl.points[1].y() - pl.points[0].y());
else if (i == n - 1)
tangent = Vec2f(pl.points[n - 1].x() - pl.points[n - 2].x(), pl.points[n - 1].y() - pl.points[n - 2].y());
else
tangent = Vec2f(pl.points[i + 1].x() - pl.points[i - 1].x(), pl.points[i + 1].y() - pl.points[i - 1].y());
float len = std::hypot(tangent.x(), tangent.y());
if (len == 0)
len = 1.0f;
tangent /= len;
// For the first and last point, if the polyline is a
// closed loop, get the tangent from the points on either
// side of the join, otherwise just use the first or last
// line.
if (i == 0) {
if (pl.points[0] == pl.points[n-1]) {
tangent = (pl.points[1] - pl.points[n-2]).template cast<float>().normalized();
} else {
tangent = (pl.points[1] - pl.points[0]).template cast<float>().normalized();
}
} else if (i == n - 1) {
if (pl.points[0] == pl.points[n-1]) {
tangent = (pl.points[1] - pl.points[n-2]).template cast<float>().normalized();
} else {
tangent = (pl.points[n-1] - pl.points[n-2]).template cast<float>().normalized();
}
} else
tangent = (pl.points[i+1] - pl.points[i-1]).template cast<float>().normalized();
Vec2f normal(-tangent.y(), tangent.x());
Point p = pl.points[i];
p.x() += scale_(normal.x() * offset);
p.y() += scale_(normal.y() * offset);
Point p = pl.points[i] + (normal * offset).template cast<coord_t>();
new_points.push_back(p);
}