GoSlice - ein Slicer für den 3D Druck

aligator

Neues Mitglied
Hallo zusammen,

ich möchte hier mein aktuelles Projekt vorstellen:

GoSlice

Ich versuch es mal so zu erklären dass es auch jemand verstehen kann, der keinen 3D Drucker hat.
Appropos, wer von euch hat denn eigentlich einen 3D Drucker?

Was ist GoSlice?
GoSlice ist ein Slicer, also ein Programm, das 3D Modelle (üblicherweise .stl) in GCode, also den Befehlen für 3D Drucker umwandelt.

Hier ein Beispiel, wie der mit GoSlice erstellte GCode in einem viewer ausguggt:
1589894446732.png

Im zweitern Bild kann man gut die einzelnen Layer erkennen:
1589894497267.png



Warum in Go?
Weil ich mich derzeit hauptsächlich mit Go befasse.

Für alle die Go nicht kennen:
https://tour.golang.org/welcome/1

Go ist sicher nicht für jeden Anwendungsfall die richtige Sprache, es gibt durchaus Dinge, die ich in Go vermisse, aber es macht richtig spaß damit zu arbeiten.
Lohnt sich auf jeden Fall mal anzuguggen.

Historie:
Da ich anfangs null Plan hatte wie ich da ran gehen soll, und leider zu diesem Thema nicht wirklich viel Information existiert, hab ich mir mal den allerersten Commit von Cura (einem sehr bekannten Slicer) angeschaut, nachdem ich diesen Kommentar gefunden hatte:
https://hackaday.com/2017/03/01/diy-3d-slicer-is-a-dynamo/#comment-3427246
Zur Referenz, hier ist dieser Commit:
https://github.com/Ultimaker/CuraEngine/commit/80dc349e2014eaa9450086c007118e10bda0b534

Mein erster Schritt war dann die vollständige Implementierung dieses Commits in Go, und als zweiten Schritt hab ich dann den Code refactored zu mehr Go-like.
Danach kamen dann weitere Features wie Infill hinzu. Natürlich fehlt da im Vergleich zu den großen "Konkurrenten" noch sehr viel, aber ich konnte bereits einen ersten Testdruck machen.
Das Ergebnis ist ganz ok für den ersten Versuch, würd ich mal sagen:
1024-1365.jpg

Die aktuell größten Probleme sind das viele Stringing und Rundungen sind unsauber. Ich vermute durch zu viele zu kleine Schritte, weil der Drucker dann immer kurz stehen bleibt, da die Befehle nicht schnell genug nach kommen.
Aber für ein so frühes Entwicklungsstadium bin ich durchaus zufrieden (man erkennt ein Schiff :))

Wie funktioniert GoSlice?
So nun will ich mal ein bisschen darauf eingehen, wie das ganze funktioniert.
Die folgenden Erklärungen beziehen sich auf die aktuelle Funktionsweise von GoSlice und das kann sich natürlich noch ändern.

Wer im Sourcecode folgen möchte, kann sich hier die Process Methode ansehen. Dort werden die einzelnen Schritte nacheinander aufgerufen.
Die Implementierungen sind dann in den entsprechenden Packages (Ordnern) zu finden.

Also prinzipiell lässt sich der Vorgang in mehrere Schritte unterteilen:

1. STL laden
Hierzu kann ich (noch) nicht allzu viel sagen, da ich hier aktuell eine Lib verwende, da ich meinen Fokus erst mal auf den Slice Vorgang selber legen wollte.
Grundsätzlich ist das .stl Format aber eigentlich recht simpel. Es kann in reiner ASCII Form oder auch Binär vorligen und enthält für die einzelnen Flächen des 3D Modells die entsprechenden Punkte.
-> was raus kommt ist eine Liste an Dreiecken mit den jeweiligen Punkten. (typ data.Model)

2. Modell Optimieren
Der Optimizer ist dafür zuständig für jede Fläche die Nachbarflächen zu finden, Duplikate festzustellen, offene Flächen finden (also Flächen mit einer Seite ohne Nachbar, was für 3D Druck nicht gut ist, Stichwort "manifold")
Außerdem werden am Ende alle Punkte in die (konfigurierbare) Mitte verschoben.
-> hier kommt ein data.OptimizedModel heraus, in das zu jeder Fläche gespeichert hat, was die nachbarn sind.

3. Modell "zerschneiden" (slicen)
Jetzt kommt das eigentlich interessante: das slicen des Models in einzelne Flächen, immer für eine andere Z-Höhe im abstand von der Konfigurierten Layer-Höhe.
Dazu wird über die SliceFace Funktion (slicer.segment.go) für jede Fläche ein Segment berechnet, dass genau in der z-höhe liegt.

Danach wird die daraus resultierende Liste an Segmenten noch mal bearbeitet:
  • Es werden sich berührende Segmente verbunden, so dass Polygone entstehen.
  • Es werden manchmal gibt es zwischen zwei halben Polygonen noch kleine Lücken. Ist dies der Fall, werden diese einfach verbunden.
  • Dann kommt es noch vor, dass zum schließen eines Polygons nur noch ganz wenig fehlt, in diesem Fall werden der Anfangs und Endpunkt einfach verbunden.
  • Am Ende werden dann noch die immer noch nicht geschlossenen Polygone und die zu kleinen Polygone einfach gelöscht.

4. Modifikationen
Dieser schritt ist im Prinzip das Preprocessing zur finalen GCode generierung.
damit das ganze etwas Struktur hat, hab ich ein Modifier interface erstellt. Dem Slicer können dann beliebig viele Modifier gegeben werden.
  • So kümmert sich einer dann um die Berechnung der Außenwände (Perimeter)
  • der nächste um das Ausfüllen der top und bottom Layer
  • und dann einer um die Berechnung, welche Fläche internen Infill benötigen.

Jeder dieser Modifier wird immer für jeden Layer ausgeführt und der Layer wird dann mit dem ersetzt was der modifier zurückliefert.
Dabei kann der Modifier dem layer Attribute mitgeben. Diese entahlten dann zum Beispiel die Perimter oder die zu füllenden Flächen.

Für die Polygon Berechnungen nutze ich aktuell die Clipper lib, welche mehr oder Weniger eins zu eins von C bzw. ursprünglich von Delphi portiert wurde.
Daher ist die Benutzung davon nicht ganz im Go Stil, aber es funktioniert.

5. GCode generierung
Hier läuft das nach einem ähnlichen Prinzip wie bei den Modifiern: Man kann beliebig viele Renderer mitgeben.
Jeder dieser Renderer kümmert sich um die Generierung eines bestimmten teils des GCode, zum Teil anhand der im vorigen Schritt berechneten Attribute.
  • Perimter
  • Infill der diversen typen
  • start / end Gcode

6. Am Ende wird dieser GCode dann einfach gespeichert als .gcode Datei.

Falls jemand Lust hat mehr über Slicer, Go und 3D Druck zu erfahren, könnt ihr gerne bei dem Projekt mit helfen :) (ein 3D Drucker ist zwar wünschenswert, aber nicht unbedingt erforderlich).

Grüße
aligator
 
Zuletzt bearbeitet:
Oben Unten