Pivy/de: Difference between revisions

From FreeCAD Documentation
(Updating to match new version of source page)
(Updating to match new version of source page)
(41 intermediate revisions by 4 users not shown)
Line 1: Line 1:
<languages/>
[http://pivy.coin3d.org/ Pivy] is a python binding library for [http://www.coin3d.org Coin3d], the 3D-rendering library used FreeCAD. When imported in a running python interpreter, it allows to dialog directly with any running Coin3d [[Scenegraph|scenegraphs]], such as the FreeCAD 3D views, or even to create new ones. Pivy is bundled in standard FreeCAD installation.
{{docnav/de
|[[Scenegraph/de|Szenengraph]]
|[[PySide/de|PySide]]
}}


[https://bitbucket.org/Coin3D/pivy/src/default/ Pivy] ist eine Python Bindungsbibliothek für [https://bitbucket.org/Coin3D/coin/wiki/Home Coin3d], die in FreeCAD verwendete 3D Rendering Bibliothek. Beim Import in einen laufenden Python-Interpreter ist es möglich, direkt mit allen laufenden Coin3d [[Scenegraph/de|Szenegraphen]], wie beispielsweise den FreeCAD 3D Ansichten, in den Dialog zutreten oder sogar neue zu erstellen. Pivy ist in der Standard FreeCAD Installation enthalten.
The coin library is divided into several pieces, coin itself, for manipulating scenegraphs and bindings for several GUI systems, such as windows or, like in our case, qt. Those modules are available to pivy too, depending if they are present on the system. The coin module is always present, and it is what we will use anyway, since we won't need to care about anchoring our 3D display in any interface, it is already done by FreeCAD itself. All we need to do is this:
<syntaxhighlight>
from pivy import coin
</syntaxhighlight>
==Accessing and modifying the scenegraph==


Die Coin3d-Bibliothek ist in mehrere Teile geteilt, Coin selbst, für die Manipulation von Szenengraphen und Bindungen für mehrere GUI-Systeme, wie z.B. Windows, oder, wie in unserem Fall, qt. Diese Module stehen auch in pivy zur Verfügung, abhängig davon, ob sie auf dem System vorhanden sind.
We saw in the [[Scenegraph]] page how a typical Coin scene is organized. Everything that appears in a FreeCAD 3D view is a coin scenegraph, organized the same way. We have one root node, and all objects on the screen are its children.
Das Coin Modul ist immer vorhanden, und es ist das, was wir ohnehin verwenden werden, somit brauchen wir uns nicht mehr um unsere Verankerung des 3D Display in jeder Oberfläche zu kümmern, dies wird bereits durch FreeCAD selbst getan. Alles, was wir tun müssen, ist dies:
{{Code|code=
from pivy import coin
}}
==Zugreifen auf und Ändern im Szenengraph==


Wir sahen in der [[Scenegraph]]-Seite, wie eine typische Münze Szene organisiert ist. Alles, was in einer FreeCAD-3D-Ansicht erscheint, ist ein Coin-Szenengraph und immer auf die gleiche Weise organisiert. Wir haben einen Wurzelknoten, und alle Objekte auf dem Bildschirm sind seine Kinder.
FreeCAD has an easy way to access the root node of a 3D view scenegraph:
<syntaxhighlight>
sg = FreeCADGui.ActiveDocument.ActiveView.getSceneGraph()
print sg
</syntaxhighlight>
This will return the root node:
<syntaxhighlight>
<pivy.coin.SoSelection; proxy of <Swig Object of type 'SoSelection *' at 0x360cb60> >
</syntaxhighlight>
We can inspect the immediate children of our scene:
<syntaxhighlight>
for node in sg.getChildren():
print node
</syntaxhighlight>
Some of those nodes, such as SoSeparators or SoGroups, can have children themselves. The complete list of the available coin objects can be found in the [http://doc.coin3d.org/Coin/classes.html official coin documentation].


FreeCAD hat eine einfache Möglichkeit, auf den Root-Knoten eines 3D-Ansicht Szenengraph zugreifen:
Let's try to add something to our scenegraph now. We'll add a nice red cube:
{{Code|code=
<syntaxhighlight>
sg = FreeCADGui.ActiveDocument.ActiveView.getSceneGraph()
col = coin.SoBaseColor()
print sg
col.rgb=(1,0,0)
}}
cub = coin.SoCube()
Dies gibt den Root-Knoten aus:
myCustomNode = coin.SoSeparator()
{{Code|code=
myCustomNode.addChild(col)
<pivy.coin.SoSelection; proxy of <Swig Object of type 'SoSelection *' at 0x360cb60> >
myCustomNode.addChild(cub)
}}
sg.addChild(myCustomNode)
Wir können die unmittelbaren Kinder unserer Szene untersuchen:
</syntaxhighlight>
{{Code|code=
and here is our (nice) red cube. Now, let's try this:
for node in sg.getChildren():
<syntaxhighlight>
print node
col.rgb=(1,1,0)
}}
</syntaxhighlight>
<div class="mw-translate-fuzzy">
See? everything is still accessible and modifiable on-the-fly. No need to recompute or redraw anything, coin takes care of everything. You can add stuff to your scenegraph, change properties, hide stuff, show temporary objects, anything. Of course, this only concerns the display in the 3D view. That display gets recomputed by FreeCAD on file open, and when an object needs recomputing. So, if you change the aspect of an existing FreeCAD object, those changes will be lost if the object gets recomputed or when you reopen the file.
Einige dieser Knoten, wie SoSeparators oder SoGroups, können selbst Kinder haben. Die vollständige Liste der verfügbaren Coin-Objekte kann man nachlesen in der [http://coin3d.bitbucket.org/Coin/classes.html offiziellen coin-Dokumentation].
</div>


Lasst uns versuchen, jetzt etwas zu unserem Szenengraph hinzuzufügen. Wir fügen einen schönen roten Würfel ein:
A key to work with scenegraphs in your scripts is to be able to access certain properties of the nodes you added when needed. For example, if we wanted to move our cube, we would have added a SoTranslation node to our custom node, and it would have looked like this:
{{Code|code=
<syntaxhighlight>
col = coin.SoBaseColor()
col = coin.SoBaseColor()
col.rgb=(1,0,0)
col.rgb=(1,0,0)
trans = coin.SoTranslation()
cub = coin.SoCube()
myCustomNode = coin.SoSeparator()
trans.translation.setValue([0,0,0])
myCustomNode.addChild(col)
cub = coin.SoCube()
myCustomNode = coin.SoSeparator()
myCustomNode.addChild(cub)
myCustomNode.addChild(col)
sg.addChild(myCustomNode)
}}
mtCustomNode.addChild(trans)
und da ist unser (schöner) roter Würfel. Jetzt wollen wir dies hier versuchen:
myCustomNode.addChild(cub)
{{Code|code=
sg.addChild(myCustomNode)
col.rgb=(1,1,0)
</syntaxhighlight>
}}
Remember that in an openInventor scenegraph, the order is important. A node affects what comes next, so you can say something like: color red, cube, color yellow, sphere, and you will get a red cube and a yellow sphere. If we added the translation now to our existing custom node, it would come after the cube, and not affect it. If we had inserted it when creating it, like here above, we could now do:
Sehen Sie? Alles ist immer noch zugänglich und on-the-fly modifizierbar. Keine Notwendigkeit, neu zu berechnen oder alles neu zu zeichnen, Coin kümmert sich schon um alles. Sie können Elemnte zum Szenengraph hinzufügen, Eigenschaften ändern, Dinge verbergen, temporäre Objekte anzeigen, einfach alles. Natürlich betrifft diese nur die Anzeige in der 3D-Ansicht. Diese Anzeige wird von FreeCAD bei öffnen einer Datei neu berechnet, und wenn ein Objekt eine Neuberechnung benötigt.
<syntaxhighlight>
Also, diese Änderungen gehen verloren, wenn Sie den Aspekt eines vorhandenen FreeCAD-Objekts ändern, wenn das Objekt neu berechnet wird oder wenn Sie die Datei wiederer öffnen.
trans.translation.setValue([2,0,0])
</syntaxhighlight>
And our cube would jump 2 units to the right.
Finally, removing something is done with:
<syntaxhighlight>
sg.removeChild(myCustomNode)
</syntaxhighlight>
==Using callback mechanisms==


Ein Schlüssel zum Bearbeiten des Szenengraphen mit Ihren Skripten ist, in der Lage zu sein, auf bestimmte Eigenschaften der Knoten die Sie hinzugefügten, bei Bedarf zugreifen zu können. Zum Beispiel, wenn wir unseren Würfel bewegen wollten, hätten wir einen SoTranslation-Knoten zu unserem benutzerdefinierten Knoten hinzugefügt, und es hätte dann so ausgesehen:
A [http://en.wikipedia.org/wiki/Callback_%28computer_science%29 callback mechanism] is a system that permits a library that you are using, such as our coin library, to call you back, that is, to call a certain function from your currently running python object. This is extremely useful, because that way coin can notify you if some specific event occurs in the scene. Coin can watch very different things, such as mouse position, clicks of a mouse button, keyboard keys being pressed, and many other things.
{{Code|code=
col = coin.SoBaseColor()
col.rgb=(1,0,0)
trans = coin.SoTranslation()
trans.translation.setValue([0,0,0])
cub = coin.SoCube()
myCustomNode = coin.SoSeparator()
myCustomNode.addChild(col)
myCustomNode.addChild(trans)
myCustomNode.addChild(cub)
sg.addChild(myCustomNode)
}}
Denken Sie daran, dass in einem OpenInventor-Szenengraph, die Reihenfolge wichtig ist. Ein Knoten beeinflusst das, was als nächstes kommt, so können Sie etwas sagen wie: Farbe rot, Würfel, Farbe gelb, Kugel, und Sie werden einen roten Würfel und eine gelbe Kugel bekommen. Wenn wir das Verschieben jetzt zu unserem vorhandenen benutzerdefinierten Knoten hinzufügen würden, würde es nach dem Würfel kommen, und diesen nicht betreffen. Wenn wir es bei der Erstellung eingefügt hätten, wie hier oben, könnten wir jetzt folgendes tun:
{{Code|code=
trans.translation.setValue([2,0,0])
}}
Und unser Würfel würde damit 2 Einheiten nach rechts springen.
Schließlich wird das Entfernen von etwas, wie folgt erledigt:
{{Code|code=
sg.removeChild(myCustomNode)
}}


==Verwenden von Rückrufmechanismen==
FreeCAD features an easy way to use such callbacks:

<syntaxhighlight>
Ein [http://en.wikipedia.org/wiki/Callback_%28computer_science%29 Rückruf-mechanismus] ist ein System, das einer Bibliothek erlaubt, wie zum Beispiel unserer Coin-Bibliothek, uns zurück zu rufen, das heißt, eine bestimmte Funktion von Ihrem laufenden Python-Objekt abzufordern. Das ist äußerst nützlich, weil COIN Sie auf diese Weise benachrichtigen kann, wenn ein bestimmtes Ereignis in der Szene eintritt. Coin kann sehr verschiedene Dinge beobachten, wie zum Beispiel Maus-Position, Mausklicks, gedrückte Tasten der Tastatur, und noch viele andere Dinge.
class ButtonTest:

def __init__(self):
FreeCAD bietet eine einfache Möglichkeit, solche Rückrufe zu verwenden:
self.view = FreeCADGui.ActiveDocument.ActiveView
{{Code|code=
self.callback = self.view.addEventCallbackPivy(SoMouseButtonEvent.getClassTypeId(),self.getMouseClick)
class ButtonTest:
def getMouseClick(self,event_cb):
def __init__(self):
event = event_cb.getEvent()
self.view = FreeCADGui.ActiveDocument.ActiveView
if event.getState() == SoMouseButtonEvent.DOWN:
self.callback = self.view.addEventCallbackPivy(SoMouseButtonEvent.getClassTypeId(),self.getMouseClick)
print "Alert!!! A mouse button has been improperly clicked!!!"
def getMouseClick(self,event_cb):
self.view.removeEventCallbackSWIG(SoMouseButtonEvent.getClassTypeId(),self.callback)
event = event_cb.getEvent()
if event.getState() == SoMouseButtonEvent.DOWN:
print "Alert!!! A mouse button has been improperly clicked!!!"
self.view.removeEventCallbackSWIG(SoMouseButtonEvent.getClassTypeId(),self.callback)
ButtonTest()
ButtonTest()
}}
</syntaxhighlight>
<div class="mw-translate-fuzzy">
The callback has to be initiated from an object, because that object must still be running when the callback will occur.
Der Rückruf muss von einem Objekt abgesetzt werden, weil das Objekt noch ausgeführt werden muss, wenn der Rückruf auftritt.
See also a [[Code_snippets#Observing_mouse_events_in_the_3D_viewer_via_Python|complete list]] of possible events and their parameters, or the [http://doc.coin3d.org/Coin/classes.html official coin documentation].
Beachten Sie auch die [[Code_snippets#Observing_mouse_events_in_the_3D_viewer_via_Python|complete list]] möglicher Ereignisse und deren Parameter, oder die [http://doc.coin3d.org/Coin/classes.html offiziellen coin-Dokumentation].
</div>


== Documentation ==
== Dokumentation ==


<div class="mw-translate-fuzzy">
Unfortunately pivy itself still doesn't have a proper documentation, but since it is an accurate translation of coin, you can safely use the coin documentation as reference, and use python style instead of c++ style (for example SoFile::getClassTypeId() would in pivy be SoFile.getClassId())
Leider hat pivy selbst noch keine richtige Dokumentation, aber da es eine genaue Übersetzung von Coin gibt, können Sie problemlos die Coin-Dokumentation als Referenz nutzen, und Python-Stil verwenden, anstatt C++-Stil (z. B. SoFile::getClassTypeId() würde in pivy zu dem werden: SoFile.getClassId())
</div>


In C++:
{{docnav|Scenegraph|PyQt}}
{{Code|code=
SoFile::getClassTypeId()
}}
In Pivy
{{Code|code=
SoFile.getClassId()
}}


* [https://grey.colorado.edu/coin3d/index.html Coin Documentation], at University of Colorado
[[Category:Poweruser Documentation]]
* [https://coin3d.bitbucket.io/Coin/index.html Coin Documentation], at BitBucket

{{docnav/de|[[Scenegraph/de|Scenegraph]]|[[PySide/de|PySide]]}}

{{Userdocnavi/de}}

[[Category:Poweruser Documentation/de]]


{{clear}}
{{clear}}
<languages/>

Revision as of 21:07, 12 March 2020

Pivy ist eine Python Bindungsbibliothek für Coin3d, die in FreeCAD verwendete 3D Rendering Bibliothek. Beim Import in einen laufenden Python-Interpreter ist es möglich, direkt mit allen laufenden Coin3d Szenegraphen, wie beispielsweise den FreeCAD 3D Ansichten, in den Dialog zutreten oder sogar neue zu erstellen. Pivy ist in der Standard FreeCAD Installation enthalten.

Die Coin3d-Bibliothek ist in mehrere Teile geteilt, Coin selbst, für die Manipulation von Szenengraphen und Bindungen für mehrere GUI-Systeme, wie z.B. Windows, oder, wie in unserem Fall, qt. Diese Module stehen auch in pivy zur Verfügung, abhängig davon, ob sie auf dem System vorhanden sind. Das Coin Modul ist immer vorhanden, und es ist das, was wir ohnehin verwenden werden, somit brauchen wir uns nicht mehr um unsere Verankerung des 3D Display in jeder Oberfläche zu kümmern, dies wird bereits durch FreeCAD selbst getan. Alles, was wir tun müssen, ist dies:

from pivy import coin

Zugreifen auf und Ändern im Szenengraph

Wir sahen in der Scenegraph-Seite, wie eine typische Münze Szene organisiert ist. Alles, was in einer FreeCAD-3D-Ansicht erscheint, ist ein Coin-Szenengraph und immer auf die gleiche Weise organisiert. Wir haben einen Wurzelknoten, und alle Objekte auf dem Bildschirm sind seine Kinder.

FreeCAD hat eine einfache Möglichkeit, auf den Root-Knoten eines 3D-Ansicht Szenengraph zugreifen:

sg = FreeCADGui.ActiveDocument.ActiveView.getSceneGraph()
print sg

Dies gibt den Root-Knoten aus:

<pivy.coin.SoSelection; proxy of <Swig Object of type 'SoSelection *' at 0x360cb60> >

Wir können die unmittelbaren Kinder unserer Szene untersuchen:

for node in sg.getChildren():
    print node

Einige dieser Knoten, wie SoSeparators oder SoGroups, können selbst Kinder haben. Die vollständige Liste der verfügbaren Coin-Objekte kann man nachlesen in der offiziellen coin-Dokumentation.

Lasst uns versuchen, jetzt etwas zu unserem Szenengraph hinzuzufügen. Wir fügen einen schönen roten Würfel ein:

col = coin.SoBaseColor()
col.rgb=(1,0,0)
cub = coin.SoCube()
myCustomNode = coin.SoSeparator()
myCustomNode.addChild(col)
myCustomNode.addChild(cub)
sg.addChild(myCustomNode)

und da ist unser (schöner) roter Würfel. Jetzt wollen wir dies hier versuchen:

col.rgb=(1,1,0)

Sehen Sie? Alles ist immer noch zugänglich und on-the-fly modifizierbar. Keine Notwendigkeit, neu zu berechnen oder alles neu zu zeichnen, Coin kümmert sich schon um alles. Sie können Elemnte zum Szenengraph hinzufügen, Eigenschaften ändern, Dinge verbergen, temporäre Objekte anzeigen, einfach alles. Natürlich betrifft diese nur die Anzeige in der 3D-Ansicht. Diese Anzeige wird von FreeCAD bei öffnen einer Datei neu berechnet, und wenn ein Objekt eine Neuberechnung benötigt. Also, diese Änderungen gehen verloren, wenn Sie den Aspekt eines vorhandenen FreeCAD-Objekts ändern, wenn das Objekt neu berechnet wird oder wenn Sie die Datei wiederer öffnen.

Ein Schlüssel zum Bearbeiten des Szenengraphen mit Ihren Skripten ist, in der Lage zu sein, auf bestimmte Eigenschaften der Knoten die Sie hinzugefügten, bei Bedarf zugreifen zu können. Zum Beispiel, wenn wir unseren Würfel bewegen wollten, hätten wir einen SoTranslation-Knoten zu unserem benutzerdefinierten Knoten hinzugefügt, und es hätte dann so ausgesehen:

col = coin.SoBaseColor()
col.rgb=(1,0,0)
trans = coin.SoTranslation()
trans.translation.setValue([0,0,0])
cub = coin.SoCube()
myCustomNode = coin.SoSeparator()
myCustomNode.addChild(col)
myCustomNode.addChild(trans)
myCustomNode.addChild(cub)
sg.addChild(myCustomNode)

Denken Sie daran, dass in einem OpenInventor-Szenengraph, die Reihenfolge wichtig ist. Ein Knoten beeinflusst das, was als nächstes kommt, so können Sie etwas sagen wie: Farbe rot, Würfel, Farbe gelb, Kugel, und Sie werden einen roten Würfel und eine gelbe Kugel bekommen. Wenn wir das Verschieben jetzt zu unserem vorhandenen benutzerdefinierten Knoten hinzufügen würden, würde es nach dem Würfel kommen, und diesen nicht betreffen. Wenn wir es bei der Erstellung eingefügt hätten, wie hier oben, könnten wir jetzt folgendes tun:

trans.translation.setValue([2,0,0])

Und unser Würfel würde damit 2 Einheiten nach rechts springen. Schließlich wird das Entfernen von etwas, wie folgt erledigt:

sg.removeChild(myCustomNode)

Verwenden von Rückrufmechanismen

Ein Rückruf-mechanismus ist ein System, das einer Bibliothek erlaubt, wie zum Beispiel unserer Coin-Bibliothek, uns zurück zu rufen, das heißt, eine bestimmte Funktion von Ihrem laufenden Python-Objekt abzufordern. Das ist äußerst nützlich, weil COIN Sie auf diese Weise benachrichtigen kann, wenn ein bestimmtes Ereignis in der Szene eintritt. Coin kann sehr verschiedene Dinge beobachten, wie zum Beispiel Maus-Position, Mausklicks, gedrückte Tasten der Tastatur, und noch viele andere Dinge.

FreeCAD bietet eine einfache Möglichkeit, solche Rückrufe zu verwenden:

class ButtonTest:
  def __init__(self):
    self.view = FreeCADGui.ActiveDocument.ActiveView
    self.callback = self.view.addEventCallbackPivy(SoMouseButtonEvent.getClassTypeId(),self.getMouseClick) 
  def getMouseClick(self,event_cb):
    event = event_cb.getEvent()
    if event.getState() == SoMouseButtonEvent.DOWN:
      print "Alert!!! A mouse button has been improperly clicked!!!"
      self.view.removeEventCallbackSWIG(SoMouseButtonEvent.getClassTypeId(),self.callback) 
 
ButtonTest()

Der Rückruf muss von einem Objekt abgesetzt werden, weil das Objekt noch ausgeführt werden muss, wenn der Rückruf auftritt. Beachten Sie auch die complete list möglicher Ereignisse und deren Parameter, oder die offiziellen coin-Dokumentation.

Dokumentation

Leider hat pivy selbst noch keine richtige Dokumentation, aber da es eine genaue Übersetzung von Coin gibt, können Sie problemlos die Coin-Dokumentation als Referenz nutzen, und Python-Stil verwenden, anstatt C++-Stil (z. B. SoFile::getClassTypeId() würde in pivy zu dem werden: SoFile.getClassId())

In C++:

SoFile::getClassTypeId()

In Pivy

SoFile.getClassId()