Line drawing function/de: Difference between revisions

From FreeCAD Documentation
No edit summary
No edit summary
 
(19 intermediate revisions by 5 users not shown)
Line 3: Line 3:
{{TOCright}}
{{TOCright}}


<span id="Introduction"></span>
==Einführung==
==Einführung==


Diese Seite zeigt, wie erweiterte Funktionalität in Python einfach erstellt werden kann. In dieser Übung werden wir ein neues Werkzeug bauen, das eine Linie zeichnet. Dieses Werkzeug kann dann mit einem FreeCAD Befehl verknüpft werden, und dieser Befehl kann von jedem Element in der Oberfläche, wie z.B. einem Menüpunkt oder einer Werkzeugleistenschaltfläche, aufgerufen werden.
Diese Seite zeigt, wie erweiterte Funktionalität in Python einfach erstellt werden kann. In dieser Übung werden wir ein neues Werkzeug bauen, das eine Linie zeichnet. Dieses Werkzeug kann dann mit einem FreeCAD Befehl verknüpft werden, und dieser Befehl kann von jedem Element in der Oberfläche, wie z.B. einem Menüpunkt oder einer Werkzeugleistenschaltfläche, aufgerufen werden.


<span id="The_main_script"></span>
==Das Hauptskript==
==Das Hauptskript==


Line 36: Line 38:
self.view.removeEventCallbackPivy(SoMouseButtonEvent.getClassTypeId(), self.callback)
self.view.removeEventCallbackPivy(SoMouseButtonEvent.getClassTypeId(), self.callback)
}}
}}
{{Top}}

<span id="Detailed_explanation"></span>
[[#top|Anfang]]

==Detaillierte Erklärung==
==Detaillierte Erklärung==


Line 46: Line 47:
}}
}}


Wenn Du in Python Funktionen aus einem anderen Modul verwenden willst, musst Du es importieren. In unserem Fall benötigen wir Funktionen aus dem [[Part_Module|Part Modul]], um die Linie zu erstellen, und aus dem Gui Modul {{incode|FreeCADGui}}, um auf die [[3D_view|3D Ansicht]] zuzugreifen. Außerdem benötigen wir die kompletten Inhalte der Coin Bibliothek, damit wir alle Coin Objekte wie {{incode|SoMouseButtonEvent}}, usw. direkt verwenden können.
Wenn Du in Python Funktionen aus einem anderen Modul verwenden willst, musst Du es importieren. In unserem Fall benötigen wir Funktionen aus dem [[Part_Workbench/de|Part-Arbeitsbereich]], um die Linie zu erstellen, und aus dem Gui Modul {{incode|FreeCADGui}}, um auf die [[3D_view/de|3D-Ansicht]] zuzugreifen. Außerdem benötigen wir die kompletten Inhalte der Coin-Bibliothek, damit wir alle Coin-Objekte wie {{incode|SoMouseButtonEvent}}, usw. direkt verwenden können.


{{Code|code=
{{Code|code=
Line 85: Line 86:


Beachte, dass es auch eine Alternative zu {{incode|addEventCallbackPivy()}} namens {{incode|addEventCallback()}} gibt, welche die Verwendung von pivy überflüssig macht. Aber da pivy ein sehr effizienter und natürlicher Weg ist, um auf jeden Teil der coin Szene zuzugreifen, ist es viel besser, es so oft wie möglich zu verwenden.
Beachte, dass es auch eine Alternative zu {{incode|addEventCallbackPivy()}} namens {{incode|addEventCallback()}} gibt, welche die Verwendung von pivy überflüssig macht. Aber da pivy ein sehr effizienter und natürlicher Weg ist, um auf jeden Teil der coin Szene zuzugreifen, ist es viel besser, es so oft wie möglich zu verwenden.
{{Top}}

[[#top|Anfang]]

{{Code|code=
{{Code|code=
def getpoint(self, event_cb):
def getpoint(self, event_cb):
}}
}}


Nun definieren wir die {{incode|getpoint()}} Funktion, die beim Drücken einer Maustaste in einer 3D Ansicht ausgeführt wird. Diese Funktion erhält ein Argument, das wir {{incode|event_cb}} aufrufen. Von diesem Ereignisrückruf aus können wir auf das Ereignisobjekt zugreifen, das verschiedene Informationen enthält (Mode Info [[Code_snippets/de#Observing_mouse_events_in_the_3D_viewer_via_Python/de|Hier]]).
Nun definieren wir die Funktion {{incode|getpoint()}}, die beim Drücken einer Maustaste in einer 3D-Ansicht ausgeführt wird. Diese Funktion erhält ein Argument, das wir {{incode|event_cb}} nennen. Von dieser Ereignisrückmeldung aus können wir auf das Ereignisobjekt zugreifen, das verschiedene Informationen enthält (weitere Informationen [[Code_snippets/de#Mausereignisse_in_der_3D-Ansicht_beobachten_mit_Python|Hier]]).


{{Code|code=
{{Code|code=
Line 128: Line 127:
}}
}}


Hier verwenden wir die {{incode|LineSegment()}} Funktion aus dem [[Part Module/de]], die eine Linie aus zwei FreeCAD Vektoren erzeugt. Die Linie ist nicht an irgendein Objekt unseres aktiven Dokuments gebunden, so dass nichts auf dem Bildschirm erscheint.
Hier verwenden wir die {{incode|LineSegment()}}-Funktion aus dem Part-Arbeitsbereich, die eine Linie aus zwei FreeCAD-Vektoren erzeugt. Die Linie ist nicht an irgendein Objekt unseres aktiven Dokuments gebunden, so dass nichts auf dem Bildschirm erscheint.


{{Code|code=
{{Code|code=
Line 147: Line 146:


Da wir mit unserer Linie fertig sind, entfernen wir den Rückrufmechanismus hier.
Da wir mit unserer Linie fertig sind, entfernen wir den Rückrufmechanismus hier.
{{Top}}

<span id="Testing_the_script"></span>
[[#top|Anfang]]

==Testen des Skripts==
==Testen des Skripts==


Line 166: Line 164:
}}
}}


Der Befehl {{incode|dir()}} ist ein eingebauter Python Befehl, der den Inhalt eines Moduls auflistet. Wir können prüfen, dass unsere {{incode|line()}} Klasse da ist mit:
<div class="mw-translate-fuzzy">
Der Befehl dir() ist ein eingebauter Python Befehl, der den Inhalt eines Moduls auflistet. Wir können sehen, dass unsere line() Klasse da ist und auf uns wartet. Nun wollen wir sie testen:
</div>


{{Code|code=
{{Code|code=
Line 174: Line 170:
}}
}}


Nun wollen wir es testen:
Now let's test it:


{{Code|code=
{{Code|code=
Line 180: Line 176:
}}
}}


Klicke zwei Mal in der 3D Ansicht, und Bingo, hier ist unsere Linie! Um es zu wiederholen, tippe einfach nochmal {{incode|exercise.line()}}.
<div class="mw-translate-fuzzy">
{{Top}}
Dann klicke zwei Mal in der 3D Ansicht, und Bingo, hier ist unsere Linie! Um es wieder zu tun, tippe einfach exercise.line() wieder ein, und wieder, und wieder... Fühlt sich toll an, oder?
<span id="Registering_the_script"></span>
</div>
==Registrierung des Skripts==


[[#top|top]]

<div class="mw-translate-fuzzy">
==Registrierung des Skripts in der FreeCAD Oberfläche==
Nun, damit unser neues Linienwerkzeug wirklich cool ist, sollte es einen Knopf auf der Oberfläche haben, damit wir nicht immer all dieses Zeug tippen müssen. Am einfachsten ist es, unser neues MyScripts Verzeichnis in einen vollständige FreeCAD Arbeitsbereich zu verwandeln. Es ist einfach, alles was benötigt wird ist eine Datei namens '''InitGui.py''' in deinem MyScripts Verzeichnis zu speichern. Die Datei InitGui.py enthält die Anweisungen zum Erstellen eines neuen Arbeitsbereichs und fügt unser neues Werkzeug hinzu. Außerdem müssen wir auch unseren Übungscode ein wenig umwandeln, damit das line()-Werkzeug als offizieller FreeCAD Befehl erkannt wird. Beginnen wir damit, eine InitGui.py-Datei zu erstellen, und schreiben wir den folgenden Code hinein:
Nun, damit unser neues Linienwerkzeug wirklich cool ist, sollte es einen Knopf auf der Oberfläche haben, damit wir nicht immer all dieses Zeug tippen müssen. Am einfachsten ist es, unser neues MyScripts Verzeichnis in einen vollständige FreeCAD Arbeitsbereich zu verwandeln. Es ist einfach, alles was benötigt wird ist eine Datei namens '''InitGui.py''' in deinem MyScripts Verzeichnis zu speichern. Die Datei InitGui.py enthält die Anweisungen zum Erstellen eines neuen Arbeitsbereichs und fügt unser neues Werkzeug hinzu. Außerdem müssen wir auch unseren Übungscode ein wenig umwandeln, damit das line()-Werkzeug als offizieller FreeCAD Befehl erkannt wird. Beginnen wir damit, eine InitGui.py-Datei zu erstellen, und schreiben wir den folgenden Code hinein:
</div>

For our new line tool to be really useful, and to avoid having to type all that stuff, it should have a button in the interface. One way to do this is to transform our new {{FileName|MyScripts}} folder into a full FreeCAD workbench. This is easy, all that is needed is to put a file called {{FileName|InitGui.py}} inside the {{FileName|MyScripts}} folder. {{FileName|InitGui.py}} will contain the instructions to create a new workbench, and add our new tool to it. Besides that we will also need to change our exercise code a bit, so the {{incode|line()}} tool is recognized as an official FreeCAD command. Let's start by creating an {{FileName|InitGui.py}} file, and writing the following code in it:


{{Code|code=
{{Code|code=
Line 206: Line 196:
}}
}}


Inzwischen solltest Du das obige Skript schon selbst verstehen, Ich denke: Wir erstellen eine neue Klasse, die wir {{incode|MyWorkbench}} nennen, wir geben ihr einen Titel {{incode|MenuText}} und wir definieren eine {{incode|Initialize()}} Funktion, die ausgeführt wird, wenn der Arbeitsbereich in FreeCAD geladen wird. In dieser Funktion laden wir den Inhalt unserer Übungsdatei ein und hängen die darin enthaltenen FreeCAD Befehle an eine Befehlsliste an. Dann erstellen wir eine Werkzeugleiste namens "Meine Skripte" und weisen ihr unsere Befehlsliste zu. Derzeit haben wir natürlich nur ein Werkzeug, so dass unsere Befehlsliste nur ein Element enthält. Sobald unser Arbeitsbereich fertig ist, fügen wir es zur Hauptoberfläche hinzu.
<div class="mw-translate-fuzzy">
Mittlerweile solltest Du das obige Skript schon selbst verstehen, Ich denke: Wir erstellen eine neue Klasse, die wir MyWorkbench nennen, wir geben ihr einen Titel (MenuText) und wir definieren eine Initialize() Funktion, die ausgeführt wird, wenn der Arbeitsbereich in FreeCAD geladen wird. In dieser Funktion laden wir den Inhalt unserer Übungsdatei ein und hängen die darin enthaltenen FreeCAD Befehle an eine Befehlsliste an. Dann erstellen wir eine Werkzeugleiste namens "Meine Skripte" und weisen ihr unsere Befehlsliste zu. Derzeit haben wir natürlich nur ein Werkzeug, so dass unsere Befehlsliste nur ein Element enthält. Sobald unser Arbeitsbereich fertig ist, fügen wir es zur Hauptoberfläche hinzu.
</div>


Aber das wird trotzdem nicht funktionieren, da ein FreeCAD Befehl auf eine bestimmte Art und Weise formatiert werden muss, um zu funktionieren. Also müssen wir unser {{incode|line()}} Werkzeug ein wenig umwandeln. Unser neues {{FileName|exercise.py}} Skript wird nun so aussehen:
<div class="mw-translate-fuzzy">
Aber das wird trotzdem nicht funktionieren, da ein FreeCAD Befehl auf eine bestimmte Art und Weise formatiert werden muss, um zu funktionieren. Also müssen wir unser line() Werkzeug ein wenig umwandeln. Unser neues exercise.py Skript wird nun so aussehen:
</div>


{{Code|code=
{{Code|code=
Line 245: Line 231:
}}
}}


Was wir hier gemacht haben, ist die Umwandlung unserer {{incode|__init__()}} Funktion in eine {{incode|Activated()}} Funktion, denn wenn FreeCAD Befehle ausgeführt werden, führen sie automatisch die {{incode|Activated()}} Funktion aus. Wir haben auch eine {{incode|GetResources()}} Funktion hinzugefügt, die FreeCAD darüber informiert, wo es ein Icon für das Werkzeug finden kann und wie der Name und der Tooltip unseres Werkzeugs lauten wird. Jedes {{FileName|jpg}}, {{FileName|png}} oder {{FileName|svg}} Bild wird als Symbol funktionieren, es kann jede beliebige Größe haben, aber es ist am besten, eine Größe zu verwenden, die dem fertigen Seitenverhältnis nahe kommt, wie 16x16, 24x24 oder 32x32.
<div class="mw-translate-fuzzy">
Dann fügen wir die {{incode|line()}} Klasse als offiziellen FreeCAD Befehl mit der {{incode|addCommand()}} Methode hinzu.
Was wir hier gemacht haben, ist die Umwandlung unserer __init__() Funktion in eine Activated() Funktion, denn wenn FreeCAD Befehle ausgeführt werden, führen sie automatisch die Activated() Funktion aus. Wir haben auch eine GetResources() Funktion hinzugefügt, die FreeCAD darüber informiert, wo es ein Icon für das Werkzeug finden kann und wie der Name und der Tooltip unseres Werkzeugs lauten wird. Jedes jpg-, png- oder svg Bild wird als Symbol funktionieren, es kann jede beliebige Größe haben, aber es ist am besten, eine Größe zu verwenden, die dem fertigen Seitenverhältnis nahe kommt, wie 16x16, 24x24 oder 32x32.
Dann fügen wir die line() Klasse als offiziellen FreeCAD Befehl mit der addCommand() Methode hinzu.
</div>

<div class="mw-translate-fuzzy">
Das war's, jetzt müssen wir nur noch FreeCAD neu starten und schon haben wir einen schönen neuen Arbeitsbereich mit unserem brandneuen Linienwerkzeug!
</div>

[[#top|top]]


Das war's, anschließend müssen wir nur noch FreeCAD neu starten und schon haben wir einen schönen neuen Arbeitsbereich mit unserem brandneuen Linienwerkzeug!
{{Top}}
<span id="So_you_want_more?"></span>
==Also willst du mehr? ==
==Also willst du mehr? ==


<div class="mw-translate-fuzzy">
Wenn Dir diese Übung gefallen hat, warum versuchst Du nicht, dieses kleine Werkzeug zu verbessern? Es gibt viele Dinge, die man tun kann, wie zum Beispiel
Wenn Dir diese Übung gefallen hat, warum versuchst Du nicht, dieses kleine Werkzeug zu verbessern? Es gibt viele Dinge, die man tun kann, wie zum Beispiel
* Benutzer Rückmeldungen hinzufügen: Bis jetzt haben wir ein sehr nacktes Tool gemacht, der Benutzer könnte etwas verloren sein, wenn er es benutzt. Wir könnten also eine Rückmeldung hinzufügen, das ihm sagt, was er als nächstes tun soll. Zum Beispiel könntest Du Meldungen an die FreeCAD Konsole ausgeben. Schaue dir das FreeCAD.Console Modul an
* Benutzer Rückmeldungen hinzufügen: Bis jetzt haben wir ein sehr nacktes Tool gemacht, der Benutzer könnte etwas verloren sein, wenn er es benutzt. Wir könnten also eine Rückmeldung hinzufügen, das ihm sagt, was er als nächstes tun soll. Zum Beispiel könntest Du Meldungen an die FreeCAD Konsole ausgeben. Schaue dir das FreeCAD.Console Modul an
Line 265: Line 245:
* Füge Ereignisse für andere Dinge hinzu: Jetzt überprüfen wir nur noch, ob es Ereignisse für die Maustaste gibt, was wäre, wenn wir auch etwas tun würden, wenn die Maus bewegt wird, wie z.B. die aktuellen Koordinaten anzeigen?
* Füge Ereignisse für andere Dinge hinzu: Jetzt überprüfen wir nur noch, ob es Ereignisse für die Maustaste gibt, was wäre, wenn wir auch etwas tun würden, wenn die Maus bewegt wird, wie z.B. die aktuellen Koordinaten anzeigen?
* Gib dem erstellten Objekt einen Namen
* Gib dem erstellten Objekt einen Namen
Zögere nicht, deine Fragen oder Ideen ins [http://forum.freecadweb.org/ Forum] zu schreiben!
</div>

Don't hesitate to ask questions or share ideas on the [https://forum.freecadweb.org/ forum]!

[[#top|top]]


Zögere nicht, deine Fragen oder Ideen im [http://forum.freecadweb.org/ Forum] zu teilen!
{{Top}}
{{Powerdocnavi{{#translation:}}}}
{{Powerdocnavi{{#translation:}}}}
[[Category:Developer Documentation{{#translation:}}]]
[[Category:Developer Documentation{{#translation:}}]]

Latest revision as of 15:34, 5 April 2024

Einführung

Diese Seite zeigt, wie erweiterte Funktionalität in Python einfach erstellt werden kann. In dieser Übung werden wir ein neues Werkzeug bauen, das eine Linie zeichnet. Dieses Werkzeug kann dann mit einem FreeCAD Befehl verknüpft werden, und dieser Befehl kann von jedem Element in der Oberfläche, wie z.B. einem Menüpunkt oder einer Werkzeugleistenschaltfläche, aufgerufen werden.

Das Hauptskript

Zuerst werden wir ein Skript schreiben, das unsere gesamte Funktionalität enthält. Dann werden wir dieses in einer Datei speichern und in FreeCAD importieren, so dass alle von uns geschriebenen Klassen und Funktionen in FreeCAD zur Verfügung stehen. Starte deinen bevorzugten Codeeditor und gib die folgenden Zeilen ein:

import FreeCADGui, Part
from pivy.coin import *

class line:

    """This class will create a line after the user clicked 2 points on the screen"""

    def __init__(self):
        self.view = FreeCADGui.ActiveDocument.ActiveView
        self.stack = []
        self.callback = self.view.addEventCallbackPivy(SoMouseButtonEvent.getClassTypeId(), self.getpoint)

    def getpoint(self, event_cb):
        event = event_cb.getEvent()
        if event.getState() == SoMouseButtonEvent.DOWN:
            pos = event.getPosition()
            point = self.view.getPoint(pos[0], pos[1])
            self.stack.append(point)
            if len(self.stack) == 2:
                l = Part.LineSegment(self.stack[0], self.stack[1])
                shape = l.toShape()
                Part.show(shape)
                self.view.removeEventCallbackPivy(SoMouseButtonEvent.getClassTypeId(), self.callback)

Anfang

Detaillierte Erklärung

import Part, FreeCADGui
from pivy.coin import *

Wenn Du in Python Funktionen aus einem anderen Modul verwenden willst, musst Du es importieren. In unserem Fall benötigen wir Funktionen aus dem Part-Arbeitsbereich, um die Linie zu erstellen, und aus dem Gui Modul FreeCADGui, um auf die 3D-Ansicht zuzugreifen. Außerdem benötigen wir die kompletten Inhalte der Coin-Bibliothek, damit wir alle Coin-Objekte wie SoMouseButtonEvent, usw. direkt verwenden können.

class line:

Hier definieren wir unsere Hauptklasse. Warum verwenden wir eine Klasse und keine Funktion? Der Grund dafür ist, dass wir unser Werkzeug "am Leben" halten müssen, während wir darauf warten, dass der Benutzer auf den Bildschirm klickt. Eine Funktion endet, wenn ihre Aufgabe erledigt ist, aber ein Objekt (eine Klasse definiert ein Objekt) bleibt am Leben, bis es zerstört wird.

"""This class will create a line after the user clicked 2 points on the screen"""

In Python kann jede Klasse oder Funktion einen Dokumentationszeichenkette (docstring) haben. Dies ist besonders in FreeCAD nützlich, denn wenn du diese Klasse im Interpreter aufrufst, wird der Beschreibungszeichenkette als Tooltip angezeigt.

def __init__(self):

Python Klassen können immer eine __init__ Funktion enthalten, die beim Aufruf der Klasse zur Erzeugung eines Objekts ausgeführt wird. Wir werden hier also alles ablegen, was sich ereignen soll, wenn unser Linienwerkzeug beginnt.

self.view = FreeCADGui.ActiveDocument.ActiveView

In einer Klasse möchte man normalerweise self. vor einem Variablennamen anhängen, damit sie für alle Funktionen innerhalb und außerhalb dieser Klasse leicht zugänglich ist. Hier werden wir self.view verwenden, um auf die aktive 3D Ansicht zuzugreifen und sie zu verändern.

self.stack = []

Hier erstellen wir eine leere Liste, die die von der getpoint() Funktion gesendeten 3D Punkte enthält.

self.callback = self.view.addEventCallbackPivy(SoMouseButtonEvent.getClassTypeId(), self.getpoint)

Das ist der wichtige Teil: Da es sich eigentlich um eine coin3D Szene handelt, verwendet FreeCAD einen Coin Rückruf Mechanismus, der es erlaubt, eine Funktion jedes Mal aufzurufen, wenn ein bestimmtes Szene Ereignis eintritt. In unserem Fall erstellen wir einen Rückruf für SoMouseButtonEvent Ereignisse, und wir binden ihn an die getpoint() Funktion. Nun wird jedes Mal, wenn eine Maustaste gedrückt oder losgelassen wird, die getpoint() Funktion ausgeführt.

Beachte, dass es auch eine Alternative zu addEventCallbackPivy() namens addEventCallback() gibt, welche die Verwendung von pivy überflüssig macht. Aber da pivy ein sehr effizienter und natürlicher Weg ist, um auf jeden Teil der coin Szene zuzugreifen, ist es viel besser, es so oft wie möglich zu verwenden.

Anfang

def getpoint(self, event_cb):

Nun definieren wir die Funktion getpoint(), die beim Drücken einer Maustaste in einer 3D-Ansicht ausgeführt wird. Diese Funktion erhält ein Argument, das wir event_cb nennen. Von dieser Ereignisrückmeldung aus können wir auf das Ereignisobjekt zugreifen, das verschiedene Informationen enthält (weitere Informationen Hier).

if event.getState() == SoMouseButtonEvent.DOWN:

Die getpoint() Funktion wird aufgerufen, wenn eine Maustaste gedrückt oder losgelassen wird. Aber wir wollen einen 3D Punkt nur dann aufnehmen, wenn er gedrückt ist, sonst würden wir zwei 3D Punkte sehr nahe aneinander bekommen. Das müssen wir also hier überprüfen.

pos = event.getPosition()

Hier erhalten wir die Bildschirmkoordinaten des Mauszeigers.

point = self.view.getPoint(pos[0], pos[1])

Diese Funktion gibt uns einen FreeCAD Vektor (x,y,z), der den 3D Punkt enthält, der auf der Brennpunktebene direkt unter unserem Mauszeiger liegt. Wenn Du Dich in der Kameraansicht befindest, stelle dir einen Strahl vor, der von der Kamera kommt, durch den Mauszeiger hindurchgeht und auf die Brennpunktebene trifft. Das ist die Position ist unseres 3D Punktes. Wenn wir uns in der orthogonalen Ansicht befinden, ist der Strahl parallel zur Blickrichtung.

self.stack.append(point)

Wir fügen unseren neuen Punkt dem Stapel hinzu.

if len(self.stack) == 2:

Haben wir schon genug Punkte? Wenn ja, dann zeichnen wir die Linie!

l = Part.LineSegment(self.stack[0], self.stack[1])

Hier verwenden wir die LineSegment()-Funktion aus dem Part-Arbeitsbereich, die eine Linie aus zwei FreeCAD-Vektoren erzeugt. Die Linie ist nicht an irgendein Objekt unseres aktiven Dokuments gebunden, so dass nichts auf dem Bildschirm erscheint.

shape = l.toShape()

Das FreeCAD Dokument kann nur Formen aus dem Part Modul übernehmen. Formen sind der grundlegendste Typ des Part Moduls. Daher müssen wir unsere Linie in eine Form konvertieren, bevor wir sie dem Dokument hinzufügen.

Part.show(shape)

Das Part Modul hat eine sehr nützliche show() Funktion, die ein neues Objekt im Dokument erzeugt und eine Form daran bindet. Wir hätten auch zuerst ein neues Objekt im Dokument erstellen können, und dann die Form manuell an dieses Objekt binden können.

self.view.removeEventCallbackPivy(SoMouseButtonEvent.getClassTypeId(), self.callback)

Da wir mit unserer Linie fertig sind, entfernen wir den Rückrufmechanismus hier.

Anfang

Testen des Skripts

Nun speichern wir unser Skript an einem Ort, an dem der FreeCAD Python Interpreter es finden kann. Beim Import von Modulen wird der Interpreter an folgenden Stellen suchen: die Python Installationspfade, das FreeCAD bin Verzeichnis und alle FreeCAD Modulverzeichnisse. Die beste Lösung ist also, ein neues Verzeichnis in einem der FreeCAD Mod Verzeichnisse anzulegen und unser Skript darin zu speichern. Erstellen wir zum Beispiel ein Verzeichnis "MyScripts" und speichern unser Skript als "exercise.py".

Nun, alles ist bereit. Lass uns FreeCAD starten, ein neues Dokument erstellen und im Python Interpreter eingeben:

import exercise

Wenn keine Fehlermeldung erscheint wurde unser Übungsskript erfolgreich geladen. Wir können nun seinen Inhalt überprüfen mit:

dir(exercise)

Der Befehl dir() ist ein eingebauter Python Befehl, der den Inhalt eines Moduls auflistet. Wir können prüfen, dass unsere line() Klasse da ist mit:

'line' in dir(exercise)

Nun wollen wir es testen:

exercise.line()

Klicke zwei Mal in der 3D Ansicht, und Bingo, hier ist unsere Linie! Um es zu wiederholen, tippe einfach nochmal exercise.line().

Anfang

Registrierung des Skripts

Nun, damit unser neues Linienwerkzeug wirklich cool ist, sollte es einen Knopf auf der Oberfläche haben, damit wir nicht immer all dieses Zeug tippen müssen. Am einfachsten ist es, unser neues MyScripts Verzeichnis in einen vollständige FreeCAD Arbeitsbereich zu verwandeln. Es ist einfach, alles was benötigt wird ist eine Datei namens InitGui.py in deinem MyScripts Verzeichnis zu speichern. Die Datei InitGui.py enthält die Anweisungen zum Erstellen eines neuen Arbeitsbereichs und fügt unser neues Werkzeug hinzu. Außerdem müssen wir auch unseren Übungscode ein wenig umwandeln, damit das line()-Werkzeug als offizieller FreeCAD Befehl erkannt wird. Beginnen wir damit, eine InitGui.py-Datei zu erstellen, und schreiben wir den folgenden Code hinein:

class MyWorkbench (Workbench):

    MenuText = "MyScripts"

    def Initialize(self):
        import exercise
        commandslist = ["line"]
        self.appendToolbar("My Scripts", commandslist)

Gui.addWorkbench(MyWorkbench())

Inzwischen solltest Du das obige Skript schon selbst verstehen, Ich denke: Wir erstellen eine neue Klasse, die wir MyWorkbench nennen, wir geben ihr einen Titel MenuText und wir definieren eine Initialize() Funktion, die ausgeführt wird, wenn der Arbeitsbereich in FreeCAD geladen wird. In dieser Funktion laden wir den Inhalt unserer Übungsdatei ein und hängen die darin enthaltenen FreeCAD Befehle an eine Befehlsliste an. Dann erstellen wir eine Werkzeugleiste namens "Meine Skripte" und weisen ihr unsere Befehlsliste zu. Derzeit haben wir natürlich nur ein Werkzeug, so dass unsere Befehlsliste nur ein Element enthält. Sobald unser Arbeitsbereich fertig ist, fügen wir es zur Hauptoberfläche hinzu.

Aber das wird trotzdem nicht funktionieren, da ein FreeCAD Befehl auf eine bestimmte Art und Weise formatiert werden muss, um zu funktionieren. Also müssen wir unser line() Werkzeug ein wenig umwandeln. Unser neues exercise.py Skript wird nun so aussehen:

import FreeCADGui, Part
from pivy.coin import *

class line:

    """This class will create a line after the user clicked 2 points on the screen"""

    def Activated(self):
        self.view = FreeCADGui.ActiveDocument.ActiveView
        self.stack = []
        self.callback = self.view.addEventCallbackPivy(SoMouseButtonEvent.getClassTypeId(), self.getpoint)

    def getpoint(self, event_cb):
        event = event_cb.getEvent()
        if event.getState() == SoMouseButtonEvent.DOWN:
            pos = event.getPosition()
            point = self.view.getPoint(pos[0], pos[1])
            self.stack.append(point)
            if len(self.stack) == 2:
                l = Part.LineSegment(self.stack[0], self.stack[1])
                shape = l.toShape()
                Part.show(shape)
                self.view.removeEventCallbackPivy(SoMouseButtonEvent.getClassTypeId(), self.callback)

    def GetResources(self):
        return {'Pixmap': 'path_to_an_icon/line_icon.png', 'MenuText': 'Line', 'ToolTip': 'Creates a line by clicking 2 points on the screen'}

FreeCADGui.addCommand('line', line())

Was wir hier gemacht haben, ist die Umwandlung unserer __init__() Funktion in eine Activated() Funktion, denn wenn FreeCAD Befehle ausgeführt werden, führen sie automatisch die Activated() Funktion aus. Wir haben auch eine GetResources() Funktion hinzugefügt, die FreeCAD darüber informiert, wo es ein Icon für das Werkzeug finden kann und wie der Name und der Tooltip unseres Werkzeugs lauten wird. Jedes jpg, png oder svg Bild wird als Symbol funktionieren, es kann jede beliebige Größe haben, aber es ist am besten, eine Größe zu verwenden, die dem fertigen Seitenverhältnis nahe kommt, wie 16x16, 24x24 oder 32x32. Dann fügen wir die line() Klasse als offiziellen FreeCAD Befehl mit der addCommand() Methode hinzu.

Das war's, anschließend müssen wir nur noch FreeCAD neu starten und schon haben wir einen schönen neuen Arbeitsbereich mit unserem brandneuen Linienwerkzeug!

Anfang

Also willst du mehr?

Wenn Dir diese Übung gefallen hat, warum versuchst Du nicht, dieses kleine Werkzeug zu verbessern? Es gibt viele Dinge, die man tun kann, wie zum Beispiel

  • Benutzer Rückmeldungen hinzufügen: Bis jetzt haben wir ein sehr nacktes Tool gemacht, der Benutzer könnte etwas verloren sein, wenn er es benutzt. Wir könnten also eine Rückmeldung hinzufügen, das ihm sagt, was er als nächstes tun soll. Zum Beispiel könntest Du Meldungen an die FreeCAD Konsole ausgeben. Schaue dir das FreeCAD.Console Modul an
  • Füge die Möglichkeit hinzu, die Koordinaten der 3D Punkte manuell einzugeben. Schaue dir die Python input() Funktion an, zum Beispiel
  • Füge die Möglichkeit hinzu, mehr als 2 Punkte hinzuzufügen
  • Füge Ereignisse für andere Dinge hinzu: Jetzt überprüfen wir nur noch, ob es Ereignisse für die Maustaste gibt, was wäre, wenn wir auch etwas tun würden, wenn die Maus bewegt wird, wie z.B. die aktuellen Koordinaten anzeigen?
  • Gib dem erstellten Objekt einen Namen

Zögere nicht, deine Fragen oder Ideen im Forum zu teilen!

Anfang