If a rear seam was projected it was not respecting seam paiting,
because it continued to search the points even if they had
'worse' point_type (e.g. common/blocker). Now the search
is aborted if there is an enforcer and it is not picked.
In the code as-is, the half-width of the skirt extrusion is
added to the user-specified distance. However, the user-specified
distance is scaled to internal units while the half-width is not,
resulting in math like "250000 + 0.125" for a skirt extrusion of
0.5mm
The fix is to include the half-width inside the scaling function
so that it is also scaled, resulting in math like "250000 + 125000".
The user-visible result is that if you have no brim and set the
skirt spacing to zero, the skirt will actually touch the model
and not be offset by half an extrusion width.
During the serialization of TriangleSelector and also during reading serialized painting data from 3MF, we cache all used states in the painted triangle mesh.
Based on this information, we can quickly determine which extruders are used and which don't.
Previously, when searching for the optimal seam candidate, no previous
seams were taken into account. This sometimes led to ugly leaps in the seam
path. Now the visibility of a seam candidate that continues from a
previous seam is reduced, meaning there is a bigger chance it will
be picked.
If there are only 2 or 3 perimeters on a layer, exactly two of them are
external and just one of them is a hole, then the seams should be
choosen next to each other on the external perimeters.
Previously there was an algirithm that was fitting a curve through
the resulting seam points. This worked for smooth models, but was
failing for some very basic cases (such as a cylinder).
The new algorithm builds on the previously implemented visibility
algirithm but does not do the curve fitting anymore.
Now the code is more separated for the four seam placement
options (rear, random, aligned, nearest).
Nearest and random are handled as one would expect.
Aligned is handled in a more "brute force" manner
(trying multiple seams and picking the best one)
and rear smartly switches between two modes
(center straight line projection and max y).
Especially in cases when the object is composed only of 2 external perimeters and 1 or 2 internal perimeters, the order of perimeters wasn't optimal and differed from the Classic perimeter generator. That caused unnecessary long travels before the external contour was printed.
The ordering of perimeters is slightly inspired by the latest changes in CuraEngine.