prusa3d / PrusaSlicer

G-code generator for 3D printers (RepRap, Makerbot, Ultimaker etc.)
https://www.prusa3d.com/prusaslicer/
GNU Affero General Public License v3.0
7.71k stars 1.93k forks source link

Hollowing ruins model geometry #13515

Open kozross opened 3 hours ago

kozross commented 3 hours ago

Description of the bug

I believe this is related to #11460 and #11053, but I figured I'd open an issue anyway, as this is much more recent than either of them. Essentially, hollowing creates a weird inconsistent surface texture, which manifests in the print: see the project and image below. What's even more concerning is that the slicer gives no indication of this.

Project file & How to reproduce

Below, some images of the resulting surfaces:

IMG_20241024_074350 IMG_20241024_074345 IMG_20241024_074323

These are not present on either the plate view or the slicer preview:

Screenshot From 2024-10-24 09-41-05 Screenshot From 2024-10-24 09-42-17

Checklist of files included above

Version of PrusaSlicer

2.8.1

Operating system

Linux

Printer model

Anycubic Photon Mono 2

Amyccoon commented 3 hours ago

I have helped @kozross to try to understand the issue we got at hand.

Here's my take and theory on what's happening, along with some pictures that I will explain what they mean.

I have checked the model througly, including the original file + the file from koz that came from Prusa. What I realised was: The hollowing shell, inner, and the outer model shell seemed all right at first, you can see the picture and their normals, the red one it's the inside, the blue one it's the outside, I have separated them in blender to take a better look.

At a closer picture, I realized that, in seemegly, random parts, there's a messed up geometry going on, whereas, the outer shell seems to have topology issues, with geometry clipping around, including lots of faces that shouldn't exist where they are, The original model DOES NOT have this, ONLY THE ONE from Prusa.

What I theorise happens it's next: Prusa, once you start hollowing, it creates a modified topology version of your object, in this case, it decimates it to heavily simplify the topology/geometry so that you can get much faster calculations in regards to the algorythms that happens and be more efficient as well. It seems to all go well, and it can create the inside hollowing, and it's all great.

Then, something does slip up. For some reasons, the "decimated" version of the model is not deleted, but rather, it's left, and for some reasons, parts where vertices are alligned with other vertices from the model itsel get meshed together, therefore you get all sorts of weird faces and topology like you got in the pictures I'm showing you. It's not the "inside" I mind you, it's the "OUTER SHELL" or the "Decimated Model" that Prusa seems to be using, according to my theory if I'm right, to be able to calculate the hollowing shell faster and more efficiently.

Now, it does seem that the whole algorythm gets borked somewhere, and it doesn't delete the actual inside mesh, but rather, has it, like I said before, mesh together with vertices from the original model in places where they allign together, therefore it creates the "random" issue we got at hand, where it feels like it's Unpredicatble and everywhere, but in reality it's not, it just so happens that the decimated topology vertices line up with the original models at those parts specifically I think, and therefore that leads to the whole model being borked and having issues printing + the model no longer being manifold, because the topology/geometry it's all messed up.

The fix I think that is the case for us here: Fixing the Prusa Slicer algorythm so that it actually does DELETE the decimated mesh it uses for optimization of it's calculation when it comes to calculating and generating the inside hollowing, instead of "letting it exist" and "mesh" and "break" the model, in "random" places.

I have tried my best to explain everything the best I can with my limited coding knowledge and what I think happens here.

PICTURES WITH EXAMPLES BELOW:

Inside and Outside shells, they all seem fine at first glance. PIC_1_

But NO! Here are all those issues, we go close up, they are found everywhere, the topology it's messed up, and it creates A LOT OF issues with the model being printed out, and leads to the issues and troubles @kozross has been facing, with all those seemgly random (but not actually if my theory's correct) issues all over it. PIC_7 PIC_6 PIC_4! PIC_3 PIC_2

As you can see, those "faces" that are "brighter" in orange are ALL the same, and they do seem quite "random" but, it's just where the vertices seem to have alligned in the right way to mesh them together and create all the separate faces. PIC_5

Jookia commented 2 hours ago

I had a quick read of the code and found that the algorithm roughly works like this:

I'm not entirely sure where things go wrong here, but it's probably with the voxel-related stuff.

Edit:

I believe the issue is that the mesh is taken, turned in to a voxel volume to create a thickness of the mesh, then the voxel volume is turned back to a mesh. Think of this as drawing a circle then pixelizing it. Now this pixelized version is turned back in to a mesh and merged with the original- This now creates a closed mesh with a hollow interior, but you still have the overlap with the pixelized mesh's outer surface and the original outer surface. There's no information about which side is the inner and which is the outer parts of the mesh. It's possible this is mitigated by having the inner part of the voxel mesh be inset, but in your case it's peeking through the outer mesh.

Sources:

https://github.com/prusa3d/PrusaSlicer/blob/master/src/libslic3r/SLA/Hollowing.cpp#L81

https://github.com/prusa3d/PrusaSlicer/blob/5dc04b4e8f14f65bbcc5377d62cad3e86c2aea36/src/libslic3r/SLAPrintSteps.cpp#L245

https://github.com/prusa3d/PrusaSlicer/blob/5dc04b4e8f14f65bbcc5377d62cad3e86c2aea36/src/libslic3r/SLA/Hollowing.cpp#L292

Amyccoon commented 1 hour ago

I had a quick read of the code and found that the algorithm roughly works like this:

* Take the current mesh

* Generate a voxel grid

* Offset within the voxel grid by a distance

* Turn this grid in to a mesh

* Swap the mesh's normals

* Merge the voxel grid with the mesh

* Drill holes for draining

I'm not entirely sure where things go wrong here, but it's probably with the voxel-related stuff.

Edit:

I believe the issue is that the mesh is taken, turned in to a voxel volume to create a thickness of the mesh, then the voxel volume is turned back to a mesh. Think of this as drawing a circle then pixelizing it. Now this pixelized version is turned back in to a mesh and merged with the original- This now creates a closed mesh with a hollow interior, but you still have the overlap with the pixelized mesh's outer surface and the original outer surface. There's no information about which side is the inner and which is the outer parts of the mesh. It's possible this is mitigated by having the inner part of the voxel mesh be inset, but in your case it's peeking through the outer mesh.

Sources:

https://github.com/prusa3d/PrusaSlicer/blob/master/src/libslic3r/SLA/Hollowing.cpp#L81

https://github.com/prusa3d/PrusaSlicer/blob/5dc04b4e8f14f65bbcc5377d62cad3e86c2aea36/src/libslic3r/SLAPrintSteps.cpp#L245

https://github.com/prusa3d/PrusaSlicer/blob/5dc04b4e8f14f65bbcc5377d62cad3e86c2aea36/src/libslic3r/SLA/Hollowing.cpp#L292

If that's the case, should it still happen when the inside hollowed shell it's separated? Here it is, showing the inside hollow shell be separated from the mesh, and the issue's still there, I posted several pics to show the faces, then an issue, then moved the face. Thank you so much for taking the time to reply and check the code and explain it by the way! Means a lot!

1 2 3 4

Amyccoon commented 1 hour ago

I had a quick read of the code and found that the algorithm roughly works like this:

* Take the current mesh

* Generate a voxel grid

* Offset within the voxel grid by a distance

* Turn this grid in to a mesh

* Swap the mesh's normals

* Merge the voxel grid with the mesh

* Drill holes for draining

I'm not entirely sure where things go wrong here, but it's probably with the voxel-related stuff.

Edit:

I believe the issue is that the mesh is taken, turned in to a voxel volume to create a thickness of the mesh, then the voxel volume is turned back to a mesh. Think of this as drawing a circle then pixelizing it. Now this pixelized version is turned back in to a mesh and merged with the original- This now creates a closed mesh with a hollow interior, but you still have the overlap with the pixelized mesh's outer surface and the original outer surface. There's no information about which side is the inner and which is the outer parts of the mesh. It's possible this is mitigated by having the inner part of the voxel mesh be inset, but in your case it's peeking through the outer mesh.

Sources:

https://github.com/prusa3d/PrusaSlicer/blob/master/src/libslic3r/SLA/Hollowing.cpp#L81

https://github.com/prusa3d/PrusaSlicer/blob/5dc04b4e8f14f65bbcc5377d62cad3e86c2aea36/src/libslic3r/SLAPrintSteps.cpp#L245

https://github.com/prusa3d/PrusaSlicer/blob/5dc04b4e8f14f65bbcc5377d62cad3e86c2aea36/src/libslic3r/SLA/Hollowing.cpp#L292

Another reason why, if the way you said it would happen, I think it's not, because, in Lychee Slicer, the same issue does not appear. Thank you so much for taking the time to reply and check the code and explain it by the way! Means a lot!

Here are the photos, no issues with topology whatsoever after doing the exact same steps, in this case, hollowing + separating both shells and taking them apart.

1 2 3

kozross commented 30 minutes ago

I can further confirm that increasing the 'quality' parameter of hollowing does not eliminate this problem.