Projekt 6: Stempel

In diesem Projekt werden wir einen Stempel modellieren, dessen Geometrie sich automatisch an die Größe des Textes anpasst, mit dem der Stempel parametrisiert wird.

Abbildung 8.: Ein parametrisierbarer Stempel

Was ist neu? 🔗

Wir werden uns mit der 2D-Grundform text befassen und sehen, dass uns bei der Verwendung von text eine bestimmte Limitation von OpenSCAD besonders zu schaffen macht. Wir werden diese Limitation trickreich umschiffen. Dabei werden uns die Boolesche Operation intersection sowie die bereits bekannte Funktion projection helfen. Darüber hinaus lernen wir die offset, minkowski- und scale-Transformationen kennen und testen aus, wie man OpenSCAD aus der Kommandozeile heraus bedienen kann.

Los geht’s 🔗

Beginnen wir mit der Erstellung eines Grundgerüsts für unsere Modellbeschreibung. Wir definieren ein Modul stempel und darin zwei Untermodule relief und korpus. Die Idee, den Stempel in zwei Untermodule aufzuteilen, kommt daher, dass wir ggf. das Stempelrelief und den Korpus des Stempels getrennt voneinander 3D-drucken wollen, um z.B. unterschiedliche Materialien verwenden zu können:

module stempel (
    txt,                       // Stempeltext
    schriftgroesse,            
    schriftart      = "Liberation Sans:style=Bold Italic", 

    stempeltiefe    = 2,       // Tiefe des Stempelreliefs
){

    module relief() {
        linear_extrude( height = stempeltiefe )
        text(
            text = txt, 
            size = schriftgroesse, 
            font = schriftart, 
            valign = "center", 
            halign = "center",
            $fn = 50
        );        
    }
    
    module korpus() {        

    }
    
    color("Peru")
    relief();
    
    korpus();
    
}

stempel("OpenSCAD",10);

Unser Modul stempel bekommt vorerst vier Parameter. Der Parameter txt bestimmt den Text, den der Stempel erhalten soll, der Parameter schriftgroesse bestimmt die (maximale) Höhe eines regulären Großbuchstabens in Millimetern und der Parameter schriftart bestimmt die zu verwendene Schriftart. Eine Übersicht über die in OpenSCAD verfügbaren Schriftarten findet sich im Menü unter Help -> Font List. Der vierte Parameter stempeltiefe definiert die Tiefe des Stempelreliefs.

Im Untermodul relief verwenden wir die 2D-Grundform text, um eine zweidimensionale Geometrie des Stempeltextes zu generieren. Wir setzen die vertikale und horizontale Ausrichtung der Schrift (valign und halign) auf center (dt. zentriert) und übergeben txt, schriftgroesse und schriftart als weitere Parameter. Wie auch bei Kreisen, Kugeln und Zylindern können wir die Feinheit der Geometrie mit der Spezialvariable $fn bestimmen. Die resultierende Textgeometrie können wir wie jede andere 2D-Grundform verwenden. In diesem Fall extrudieren (linear_extrude) wir den Text auf die gewünschte Tiefe des Stempelreliefs.

Um nun in unserer Modellbeschreibung fortzufahren, wäre es nützlich, wenn wir Breite und Höhe des Textes herausbekommen könnten. Die Höhe wird ähnlich der Schriftgröße sein. Die Breite hängt vom jeweiligen Stempeltext txt ab. Auch wenn es verwundern mag: es gibt in OpenSCAD keine Möglichkeit, diese Maße herauszufinden! Diese Limitation von OpenSCAD macht es sehr schwer, Geometrien zu definieren, die sich automatisch auf einen gegebenen Text anpassen. Wir wollen es an dieser Stelle dennoch probieren und müssen dafür tief in die Trickkiste greifen. Wir beginnen damit, dass wir ein weiteres Untermodul textflaeche definieren und dort noch einmal den Text als 2D-Grundform erstellen und auf 3 Millimeter extrudieren:

module stempel (
	/* ... */
){

    module textflaeche() {
        linear_extrude( height = 3 )
        text(
            text = txt, 
            size = schriftgroesse, 
            font = schriftart, 
            valign = "center", 
            halign = "center",
            $fn = 50
        );        
    }
    
    !textflaeche(); // debug

	/* ... */
    
}
/* ... */

Es empfiehlt sich, das Untermodul textflaeche einmal unter der Moduldefinition zu instanziieren und der Instanz ein !-Zeichen voranzustellen. Auf diese Weise kann man die schrittweise Konstruktion der textflaeche besser verfolgen. Nun wird es trickreich. Wir richten unseren Text auf, indem wir ihn um 90 Grad um die X-Achse drehen. Dann nutzen wir die projection-Transformation aus, um den stehenden Text auf die X-Y-Ebene zu projizieren. Anschließend verbinden wir die projizierten “Schatten” der einzelnen Buchstaben mit der hull-Transformation:

module stempel (
	/* ... */
){

    module textflaeche() {
    	hull()
        projection()
        rotate([90,0,0])
        linear_extrude( height = 3 )
        text(
            text = txt, 
            size = schriftgroesse, 
            font = schriftart, 
            valign = "center", 
            halign = "center",
            $fn = 50
        );        
    }
    
    !textflaeche(); // debug

	/* ... */
    
}
/* ... */

Es empfiehlt sich, die beschriebenen Schritte einzelnd mittels Vorschau (F5) bzw. Berechnung (F6) nachzuvollziehen (Abbildung 8.). Nutzt man die Berechnung anstatt der Vorschau werden 2D-Formen besser als solche erkennbar.

Abbildung 8.: Durch Ausnutzen von projection und hull bekommen wir ein Rechteck, dass die Breite des Textes hat

Wir sind bei der Ermittlung der Textfläche schon ein gutes Stück weiter gekommen. Wir haben jetzt eine 2D-Form, die zumindest schonmal die Breite unseres Textes hat. Wenden wir den Trick einfach noch einmal an, nur drehen wir jetzt nicht um die X-Achse, sondern um die Y-Achse:

module stempel (
	/* ... */
){

    module textflaeche() {
    	hull()
        projection()
        rotate([90,0,0])
        linear_extrude( height = 3 )
        text(
            text = txt, 
            size = schriftgroesse, 
            font = schriftart, 
            valign = "center", 
            halign = "center",
            $fn = 50
        );        

        hull()
        projection()    
        rotate( [0, 90, 0] )
        linear_extrude( height = 1 )
        text(
            text = txt, 
            size = schriftgroesse, 
            font = schriftart, 
            valign = "center", 
            halign = "center",
            $fn = 50
        );        
    }
    
    !textflaeche(); // debug

	/* ... */
    
}
/* ... */

Jetzt haben wir eine weitere 2D-Form, die dieses Mal die Höhe unseres Textes hat. Man beachte, dass wir diesmal nur um einen Millimeter extrudiert haben. Was uns jetzt noch fehlt ist ein Weg, diese beiden 2D-Formen zusammenzuführen. Wenn wir die Formen jeweils um eine geeignete Länge extrudieren und dann übereinanderlegen, dann sollte der Schnitt dieser beiden Formen genau die gesuchte Geometrie haben. Für die “geeignete Länge” der ersten Form müssen wir Abschätzen, wie hoch der Text maximal sein wird. Hier können wir einfach 3 x schriftgroesse annehmen. Bei der Länge können wir die Anzahl der Zeichen im Text nehmen, diese mit der Schriftgröße multiplizieren und dann noch einen Sicherheitsfaktor von zwei mit hinzuziehen. Mit diesen Werten können wir nun die 2D-Formen extrudieren und durch geeignete Drehung und Verschiebung überlappen lassen:

module stempel (
	/* ... */
){

    module textflaeche() {
        translate( [0,0,-1] )
        rotate( [-90,0,0] )
        translate( [0, 0, -(3 * schriftgroesse) / 2] )
        linear_extrude( height = 3 * schriftgroesse )
        hull()
        projection()
        rotate([90,0,0])
        linear_extrude( height = 3 )
        text(
            text = txt, 
            size = schriftgroesse, 
            font = schriftart, 
            valign = "center", 
            halign = "center",
            $fn = 50
        );
        
        geschaetzte_laenge = len(txt) * schriftgroesse * 2;        
        
        rotate( [0, -90, 0] )
        translate( [0, 0, -geschaetzte_laenge / 2] )
        linear_extrude( height = geschaetzte_laenge )
        hull()
        projection()    
        rotate( [0, 90, 0] )
        linear_extrude( height = 1 )
        text(
            text = txt, 
            size = schriftgroesse, 
            font = schriftart, 
            valign = "center", 
            halign = "center",
            $fn = 50
        );        
    }
    
    !textflaeche(); // debug

	/* ... */
    
}
/* ... */

Man beachte die Verwendung der Funktion len, um die Anzahl der Zeichen des Stempeltextes zu ermitteln. In gleicher Weise funktioniert die Funktion len auch, um die Anzahl der Elemente in einem Feld zu ermitteln. Nun sind wir fast am Ziel! Mit der Booleschen Operation intersection können wir nun den Schnitt unserer beiden 3D-Formen erzeugen und anschließend mit einer weiteren Anwendung von projection zu einer 2D-Form umwandeln:

module stempel (
	/* ... */
){

    module textflaeche() {
        projection()
        intersection(){
            translate( [0,0,-1] )
            rotate([-90,0,0])
            translate([0,0,-(3 * schriftgroesse) / 2])
            linear_extrude( height = 3 * schriftgroesse )
            hull()
            projection()
            rotate([90,0,0])
            linear_extrude( height = 3 )
            text(
                text = txt, 
                size = schriftgroesse, 
                font = schriftart, 
                valign = "center", 
                halign = "center",
                $fn = 50
            );
            
            geschaetzte_laenge = len(txt) * schriftgroesse * 2;        
            
            rotate( [0, -90, 0] )
            translate( [0, 0, -geschaetzte_laenge/2] )
            linear_extrude( height = geschaetzte_laenge )
            hull()
            projection()    
            rotate( [0, 90, 0] )
            linear_extrude( height = 1 )
            text(
                text = txt, 
                size = schriftgroesse, 
                font = schriftart, 
                valign = "center", 
                halign = "center",
                $fn = 50
            );        
        }
    }
    
    !textflaeche(); // debug

	/* ... */
    
}
/* ... */
Abbildung 8.: Geschafft! Eine 2D-Fläche, die sich automatisch an die Dimension des Textes anpasst

Wenn man nun das !-Zeichen wieder entfernt und eine Vorschau auslöst (F5) kann man sehen, dass wir unser Ziel erreicht haben (Abbildung 8.). Wir haben eine 2D-Fläche erzeugt, die sich automatisch an die Größe des Stempeltextes anpassen kann! Mit Hilfe dieser speziellen Fläche werden wir nun den Rest des Stempels konstruieren. Bevor wir fortfahren, sollten wir sicherstellen, dass wir unsere “debug”-Instanz der textflaeche jetzt wieder entfernen.

Nun widmen wir uns wieder dem Untermodul relief und nutzen unser Modul textflaeche, um den Reliefuntergrund zu beschreiben:

module stempel (
    txt,                       // Stempeltext
    schriftgroesse,            
    schriftart      = "Liberation Sans:style=Bold Italic", 

    stempeltiefe = 2,          // Tiefe des Stempelreliefs
    rand         = 5,          // Abstand zum Text
    kissentiefe  = 2,          // Tiefe des Reliefuntergrunds
){

	/* ... */

    module relief() {
        linear_extrude( height = stempeltiefe )
        text(
            text = txt, 
            size = schriftgroesse, 
            font = schriftart, 
            valign = "center", 
            halign = "center",
            $fn = 50
        );        

        // reliefuntergrund
        translate( [0, 0, stempeltiefe] )
        linear_extrude( height = kissentiefe)
        offset( delta = rand )
        textflaeche();
    }
    
	/* ... */    
}
/* ... */

Wir erweitern unser Modul stempel um die Parameter rand und kissentiefe, die einen Abstand zum Text und die Tiefe des Reliefuntergrunds festlegen. Den Reliefuntergrund modellieren wir auf Basis der textflaeche und erweitern diese mit der Transformation offset. Diese Transformation dehnt die nachfolgende 2D-Geometrie um den Parameter delta aus bzw. schrumpft die Geometrie falls delta negativ ist. Anschließend extrudieren wir unsere gedehnte textflaeche auf kissentiefe und positionieren sie mittels Verschiebetransformation oberhalb des Stempeltextes (translate( [0, 0, stempeltiefe] )).

Es wäre schön, wenn wir unserem Stempeltext noch wahlweise eine Umrandung geben könnten. Auch diese können wir auf Basis unserer textflaeche konstruieren:

module stempel (
    txt,                       // Stempeltext
    schriftgroesse,            
    schriftart      = "Liberation Sans:style=Bold Italic", 

    stempeltiefe = 2,          // Tiefe des Stempelreliefs
    rand         = 5,          // Abstand zum Text
    kissentiefe  = 2,          // Tiefe des Reliefuntergrunds

    umrandung        = true,   // Umrandung oder nicht
    umrandung_dicke  = 2,      // Wandungsstaerke der Umrandung
    umrandung_radius = 2,      // Eckenradius der Umrandung
){

	/* ... */

    module relief() {
        linear_extrude( height = stempeltiefe )
        text(
            text = txt, 
            size = schriftgroesse, 
            font = schriftart, 
            valign = "center", 
            halign = "center",
            $fn = 50
        );        

        // reliefuntergrund
        translate( [0, 0, stempeltiefe] )
        linear_extrude( height = kissentiefe)
        offset(delta = rand + (umrandung ? umrandung_dicke : 0))
        textflaeche();

        // umrandung
        if (umrandung) {
            
            linear_extrude( height = stempeltiefe )
            difference() {
                minkowski() {
                    offset( delta = rand - umrandung_radius )
                    textflaeche();
                    
                    circle( r = umrandung_radius + umrandung_dicke, $fn = 36);
                }
                
                minkowski() {
                    offset( delta = rand - umrandung_radius )
                    textflaeche();
                    
                    circle( r = umrandung_radius, $fn = 36);
                }
            }

        } // if umrandung
    } // module relief
    
	/* ... */    
}
/* ... */

Für die optionale Umrandung erweitern wir das Modul stempel um drei weitere Parameter umrandung, umrandung_dicke und umrandung_radius, die die Umrandung charakterisieren. Zunächst passen wir unseren Reliefhintergrund an. Wenn es eine Umrandung gibt, dann fügen wir dem Parameter delta der offset-Transformation die Dicke der Umrandung hinzu.

Die Umrandung selbst modellieren wir innerhalb einer if-Fallunterscheidung, so dass die Umrandung nur dann zu einem Teil der Geometriebeschreibung wird, wenn der Parameter umrandung auf true gesetzt ist. Wir konstruieren die Umrandung als Boolesche Differenz zweier 2D-Geometrien, die wir erst dann mittels linear_extrude zu einer 3D-Geometrie umwandeln. Die beiden 2D-Geometrien sind zwei Minkowski-Summen. Die Minkowski-Summe zweier Punktmengen ist die Menge der paarweise addierten Punkte aus beiden Mengen. Im Falle der Minkowski-Summe eines Rechtecks und eines Kreises kann man sich einfach vorstellen, dass der Kreis an alle vier Ecken des Rechtecks kopiert und anschließend die konvexe Hülle des Ganzen gebildet wird (Abbildung 8.).

Abbildung 8.: Minkowski-Summe (rechts) eines Rechteck und eines Kreises (links)

Für die Beschreibung der Umrandung nutzen wir die minkowski-Transformation, um der textflaeche abgerundete Ecken zu geben. Wir benötigen zwei Flächen. Eine große, die die Außenkante der Umrandung beschreibt und eine kleine, die die Innenkante der Umrandung beschreibt. Die kleinere Fläche wird anschließend von der größeren abgezogen. Da bei der minkowski-Transformation der Radius des Kreises zur Erweiterung der textflaeche mittels offset hinzukommt, müssen wir den Radius innerhalb der offset-Transformation berücksichtigen und vom rand abziehen.

Da die minkowski-Transformation nicht damit klarkommt, wenn der Radius der Kreise 0 wird, müssen wir noch eine Fallunterscheidung vornehmen:

module stempel (
	/* ... */
){
	/* ... */

    module relief() {
		/* ... */

        // umrandung
        if (umrandung) {
            
            linear_extrude( height = stempeltiefe )
            difference() {
                minkowski() {
                    offset(
                        delta = rand - 
                                umrandung_radius + 
                                ((umrandung_radius > 0) ? 0 : umrandung_dicke)
                    )
                    textflaeche();
                    
                    if (umrandung_radius > 0)
                    circle( r = umrandung_radius + umrandung_dicke, $fn = 36);
                }
                
                minkowski() {
                    offset( delta = rand - umrandung_radius )
                    textflaeche();
                    
                    if (umrandung_radius > 0)
                    circle( r = umrandung_radius, $fn = 36);
                }
            }

        } // if umrandung
    } // module relief
    
	/* ... */    
}
/* ... */

Nun werden die Kreise innerhalb der Minkowski-Summen nur in die Geometriebeschreibung übernommen, wenn der Radius der Kreise größer 0 ist. Gleichzeitig wird die offset-Transformation der größeren Fläche so angepasst, dass im Falle eines Radius von null die Dicke der Umrandung nicht über den Kreis sondern über die offset-Transformation hergestellt wird.

Damit haben wir die Beschreibung des Stempelreliefs abgeschlossen und können uns jetzt der Geometriebeschreibung des Stempelkorpus zuwenden:

module stempel (
	/* ... */
    stempelrelief      = true, // erzeugt das Stempelrelief     
    stempelkorpus      = true, // erzeugt den Stempelkorpus

    korpus_hoehe       = 10,   // Höhe des Hauptkörpers
    korpus_basis       = 2,    // Höhe der Hauptkörperbasis
    korpus_rand        = 1.6,  // Wandungsstärke der Reliefaufnahme
    korpus_zugabe      = 0.5,  // Vergrößerung der Reliefaufnahme für den
                               // zweiteiligen Druck
    korpus_innentiefe  = 1,    // Tiefe der Reliefaufnahme
    korpus_radius      = 1,    // Radius der Außenkanten des Hautpkörpers
    korpus_ruecksprung = 3,    // Rücksprung der oberen Fläche des Hauptkörpers
    korpus_griff_dm    = 25,   // Durchmesser der Griffkugel
    korpus_griff_hoehe = 40,   // Höhe des Griffkugelzentrums über Hauptkörper
    korpus_griff_rand  = 3,    // unterer Steg des Griffes
    korpus_griff_vdm   = 5     // Durchmesser der "Vorne"-Markierung
){
	/* ... */

    module korpus() {        

        korpus_null = stempeltiefe + kissentiefe - korpus_innentiefe;

        module basis( ruecksprung = 0) {
            minkowski() {
                offset(
                    delta = rand + 
                            (umrandung ? umrandung_dicke : 0) + 
                            korpus_rand +                     
                            (stempelrelief ? 0 : korpus_zugabe) -
                            korpus_radius - 
                            ruecksprung
                )        
                textflaeche();
                
                if (korpus_radius > 0)
                circle( r = korpus_radius, $fn = 36);
            }        
        }            

    }
    
	/* ... */    
}
/* ... */

Wir beginnen auch hier damit, unser Modul stempel um eine ganze Reihe von Parametern zu erweitern. Hier sind insbesondere die Parameter stempelrelief und stempelkorpus hervorzuheben. Sie steuern, ob eine Geometriebeschreibung für das Relief bzw. den Korpus erzeugt wird. Wir werden diese Informationen nicht nur später bei der Instanziierung der Untermodule nutzen, sondern auch innerhalb des Untermoduls korpus. Wir verzichten an dieser Stelle auf eine ausführliche Beschreibung der zahlreichen weiteren Parameter, da sich ihre Bedeutung aus den Kommentaren und ihrer Verwendung in der Geometriebeschreibung ergeben wird.

Im Untermodul korpus definieren wir zunächst die Variable korpus_null, die die Höhe der Unterkante des Korpus beschreibt. Da der Korpus auf der Unterseite eine Aussparung haben soll, die das Stempelrelief aufnimmt, liegt die Unterkante nicht parallel zu stempeltiefe + kissentiefe sondern um korpus_innentiefe niedriger. Als nächstes definieren wir ein Hilfsmodul basis, das eine zweidimensionale Beschreibung der Korpusgrundform liefert. Wie auch das Stempelrelief baut diese Grundform auf der textflaeche auf, die mittels offset-Transformation ausgedehnt und mittels minkowski-Transformation abgerundet wird. Die Ausdehnung der Basisfläche ist abhängig von einigen Parametern und berücksichtigt z.B. ob es eine Umrandung gibt. Über den Parameter ruecksprung kann die Basisfläche im weiteren Verlauf der Modellbeschreibung angepasst werden, ohne eine weitere offset-Transformation nutzen zu müssen. Die Prüfung, ob gleichzeitig auch ein stempelrelief erzeugt wird, hat folgenden Hintergrund: wenn das Stempelrelief nicht gleichzeitig erzeugt wird, gehen wir davon aus, dass das Stempelkorpus und Stempelrelief getrennt hergestellt und nachträglich zusammengefügt werden. Damit man einen Einfluss auf die Passgenauigkeit hat, gibt es den Parameter korpus_zugabe. Man kann damit die Aussparung auf der Unterseite des Korpus etwas größer machen. Entsprechend muss dies auch in der Ausdehnung der Basisfläche berücksichtigt werden. Werden hingegen Stempelrelief und Stempelkorpus gleichzeitig erzeugt, gehen wir davon aus, dass sie auch am Stück hergestellt werden und der Bedarf nach einer Anpassung entfällt.

Der Hautpkörper des Stempelkorpus wird mittels einer hull-Transformation erzeugt, von dem anschließend die Reliefaussparung mittels Boolescher Differenz abgezogen wird:

module stempel (
	/* ... */
){
	/* ... */

    module korpus() {        

		/* ... */

        // hauptkörper
        difference() {
            hull(){
                translate([
                    0,
                    0,
                    korpus_null
                ])
                linear_extrude( height = korpus_basis )
                basis();

                translate([
                    0,
                    0,
                    korpus_null + korpus_hoehe
                ])
                linear_extrude( height = 0.01 )
                basis( korpus_ruecksprung );
            }
            
            translate( [0, 0, stempeltiefe] )
            linear_extrude( height = kissentiefe)
            offset(
            	delta = rand + 
            			(umrandung ? umrandung_dicke : 0) + 
            			(stempelrelief ? 0 : korpus_zugabe)
           	)
            textflaeche();
        }

    }
    
	/* ... */    
}
/* ... */

Der untere Teil des Hauptkörpers besteht aus einer basis mit Höhe korpus_basis. Hierdurch entsteht eine kleine Kante. Der obere Teil besteht aus einer mit korpus_ruecksprung verkleinerten Basis, die nur ein hundertstel Millimeter dick ist. Dieser Teil dient nur als “Deckel”, während die Seitenteile durch die hull-Transformation erzeugt werden. Die Aussparung für das Stempelrelief wird direkt auf Basis der textflaeche erzeugt, mit offset auf die richtige Größe gebracht, analog zur Basis des Stempelreliefs positioniert und schließlich mittels Boolescher Differenzoperation vom Hauptkörper abgezogen.

Was nun noch fehlt ist der Stempelgriff:

module stempel (
	/* ... */
){
	/* ... */

    module korpus() {        

		/* ... */

        // griff kugel
        translate([
            0, 
            0, 
            korpus_null + korpus_hoehe + korpus_griff_hoehe
        ])
        sphere(d = korpus_griff_dm, $fn = 50);
        
        // griff vorne knubbel
        color("Silver")
        translate([
            0, 
            korpus_griff_dm / 2, 
            korpus_null + korpus_hoehe + korpus_griff_hoehe
        ])
        scale( [1, 0.5, 1] )
        sphere(d = korpus_griff_vdm, $fn = 25);
        
        // griff hals
        translate( [0, 0, korpus_null + korpus_hoehe])
        rotate_extrude( $fn = 50)
        difference() {
            square([
                korpus_griff_dm / 2 - korpus_griff_rand, 
                korpus_griff_hoehe
            ]);  
            
            translate([
                korpus_griff_dm / 2, 
                korpus_griff_hoehe / 2 
            ])
            scale( [0.4, 1] )
            circle( d = korpus_griff_hoehe, $fn = 50 );
        }

    }
    
	/* ... */    
}
/* ... */

Der Stempelgriff besteht aus einer Kugel, einem darunter liegenden Hals und einem taktilen Indikator, der die Vorderseite des Stempels anzeigt. Die Kugel besteht lediglich aus einer passend verschobenen sphere-Grundform. Der Vorne-Indikator besteht aus einer kleinen Kugel, die wir zusätzlich mittels der scale-Transformation (dt. skalieren) in Y-Richtung auf 50% gestaucht haben. Den Hals beschreiben wir über eine Rotationsextrusion (Abbildung 8.). Als 2D-Grundform nehmen wir hierfür ein Rechteck und schneiden auf einer Seite des Rechtecks einen gestauchten Kreis mittels Boolescher Differenz aus. Durch die Rotationsextrusion wird dann aus dieser 2D-Geometrie ein konkaver, dreidimensionaler Hals.

Abbildung 8.: Erzeugung des Stempelhalses mittels Rotationsextrusion

Unser Stempelmodul ist nun fast fertig. Wir müssen nur noch die Parameter stempelrelief und stempelkorpus bei der Instanziierung der Untermodule berücksichtigen:

module stempel (
	/* ... */
){
	/* ... */

    if (stempelrelief) {
        color("Peru")
        rotate([0, stempelkorpus ? 0 : 180, 0])            
        relief();
    }
    
    if (stempelkorpus) {        
        korpus();
    }

}
/* ... */

Im Falle des Stempelreliefs haben wir noch eine Rotationstransformation hinzugefügt, die dafür sorgt, dass das Relief umgedreht wird, sollte es alleine berechnet werden. Dies erleichtert den anschließenden 3D-Druck des Reliefs.

Ein kleiner Tipp zum Schluss: Wenn wir in unserem Text spezielle Unicode-Zeichen verwenden wollen, können wir diese mittels der chr-Funktion von OpenSCAD kodieren. Die “Gegenrichtung” bildet die Funktion ord. Sie liefert für ein gegebenes Zeichen den zugehörigen Unicode. Da viele Schriftarten auch grafische Symbole als Zeichen enthalten, kann dies ein Weg sein, diese Symbole innerhalb von OpenSCAD als 2D-Grundform zu nutzen. So liefert text( chr( 9786 ) ); zum Beispiel ein lachendes Gesicht als 2D-Geometrie zurück :).

OpenSCAD in der Kommandozeile 🔗

Wir haben es geschafft, die Stempelgeometrie so zu beschreiben, dass sie sich automatisch auf die Dimension des jeweiligen Textes anpasst. Hierdurch eignet sich das Modul stempel recht gut, um es als Beispiel für eine automatisierte Geometrieerstellung über die Kommandozeile zu nutzen. Ein solches Vorgehen könnte man dazu nutzen, die Erstellung von Stempeln über eine alternative Schnittstelle anzubieten.

Um automatisiert Stempel aus der Kommandozeile zu erzeugen, muss unsere Stempelinstanz innerhalb der .scad-Datei mittels Variablen parametrisiert werden:

/* ... */

st  = "OpenSCAD";
stg = 10;

stempel(st,stg);

Die Variablen müssen hierbei schon mit Beispielwerten initialisiert werden und dürfen nicht undefiniert bleiben. Jetzt können wir die Variablen aus der Kommandozeile heraus setzen:

$ OpenSCAD -o stempel.stl -D 'st="3D-Druck!"' -D 'stg=15' stempel.scad 

Die Option -o stempel.stl gibt die Ausgabedatei an. Die Option -D 'st="3D-Druck!"' setzt die Variable st auf den Wert “3D-Druck” und die Option -D 'stg=15 setzt den Parameter stg auf 15. Das letzte Argument stempel.scad ist der Name der .scad-Datei, in der sich unser Modul stempel und die mit den Variablen st und stg parametrisierte Stempelinstanz befindet.

Download der OpenSCAD-Datei dieses Projektes

← Projekt 5: Stiftehalter
Projekt 7: Flammenskulptur →