Ultimaker / CuraEngine

Powerful, fast and robust engine for converting 3D models into g-code instructions for 3D printers. It is part of the larger open source project Cura.
https://ultimaker.com/en/products/cura-software
GNU Affero General Public License v3.0
1.68k stars 882 forks source link

Fix xy-support distance #2000

Closed casperlamboo closed 9 months ago

casperlamboo commented 9 months ago

Some history

PR with some fixes regrading the xy-distance. The XY-distance was a bit broken before. The issues were introduces by a feature called varying xy-distance (https://ultimaker.atlassian.net/browse/CURA-10297). The feature was nice, in theory, but the implementation was a bit over complicated. In cura we have two xy-distances; xy-disance and minimum xy-distance. The idea was that for vertical walls we would use the xy-distance to avoid support from coming too close to the walls. However, for angled walls we would use the min xy-distance. Reason for this is that, when using the xy-distance, the support would be to far away and not properly support the walls.

This has always worked quite nicely in the past. However, there is one somewhat unexpected consequence from this behavior, and that is that when a wall transitions from being "angled" to being completely vertical the xy distance would jump from the min xy-distance to the xy-distance.

CURA-10220 drawio2

In the example this behavior is a bit odd, but quite alright. However, when we have models with "organic near straight walls" the behavior would be come unpredictable and a bit chaotic. Case in point the screen shot below. Here the xy distance is visualized.

Screenshot 2023-02-15 at 19 21 37

This is solved using the varying xy-distance feature. Here the xy-distance is gradually changes with the wall angle. So for completely vertical walls the xy-distance is used, but as the wall changes angle the xy-distance gradually transitions with this angle.

When the feature first was implement a voronoi diagram was used to calculate the distance between a point on the current layer and the closest point to this point on the next layer. As you can imagine this produced some weird results. The particular code in question is now changed in this PR by a simple for loop that for each point $p_a$ on the current layer loops through all points $p_b$ of the next layer in order to find the closes point to $p_a$.

Reviewer, please pay attention to the performance of this ticket; the algorithm in question is changed from a $O(\log(n))$ algorithm to a $O(n^2)$ algorithm. However, since voronoi performance was a bit unpredictable anyways, and the new code is much simpler I don't think this is a big issue.

xy-distance before

Screenshot 2023-12-19 at 10 10 16

xy-distance after

Screenshot 2023-12-19 at 10 04 05