Export und Import von Objekten
Export und Import von Objekten
Hallo zusammen!
Ich suche gerade eine Möglichkeit Python-Objekte (wie z.B.: eine Liste von Edges, oder einzelne Edges und Vertexes auf der Festplatte zu speichern und später wieder zu laden)
Mit dem pickle Modul funktioniert das leider nicht:
"TypeError: can't pickle TopoShape objects"
Gibt es da eine andere Möglichkeit? oder ist das vielleicht aufgrund der Datenstruktur garnicht möglich?
Ich suche gerade eine Möglichkeit Python-Objekte (wie z.B.: eine Liste von Edges, oder einzelne Edges und Vertexes auf der Festplatte zu speichern und später wieder zu laden)
Mit dem pickle Modul funktioniert das leider nicht:
"TypeError: can't pickle TopoShape objects"
Gibt es da eine andere Möglichkeit? oder ist das vielleicht aufgrund der Datenstruktur garnicht möglich?
Re: Export und Import von Objekten
Für Shapes gibt ein eigenes Dateiformat. .brep order .brp. Eine Shape hat die Methoden exportBrep und importBrep um mit diese Dateien zu erzeugen oder zu lesen.MarvinK wrote:Gibt es da eine andere Möglichkeit?
Darüber hinaus wäre es denkbar das Pickle protokoll zu ünterstüzen, indem man __getstate__ = exportBrepToString und __setstate__ = importBrepFromString setzt. Aber das wäre dann mit Änderungen am c++ code verbunden. Ob das sinvoll wäre ist eine andere Frage. Schließlich haben wir Pickle aus Sicherheitsgründen aus dem FreeCAD Std Dateiformat verbannt.
EDIT: Also __setstate__ müsste wohl vorher noch PyInit aufrufen.
EDIT2: PyInit sollte nicht nötig sein. Allerdigs gibt es die Klasse TopoShape nicht unter dem Namen Part.TopoShape.
Und Part.Shape scheint nicht der gleiche Typ zu sein
Code: Select all
>>> App.ActiveDocument.Box.Shape.__class__) is Part.Shape
false
>>> type(Part.makeBox(1,2,3)) is Part.Shape
False
Re: Export und Import von Objekten
Ja, davon hatte ich gelesen. Auch das pickle bewusst "verbannt" wurde.
Mein Ziel ist es nur eine selektierte Auswahl von Edges und Faces zu exportieren und nicht das ganze Shape.
Hmm...
Vielleicht erst aus der Selektion ein neues Shape erzeugen....
Spricht da irgendwas dagegen?
(Gesprochen in "schlechtem" Pseudocode)
Also gegen: getSelectionEx()[0] -> erzeuge Shape -> exportiere Shape -> importiere Shape -> meineEdges = Shape.Edges
Mein Ziel ist es nur eine selektierte Auswahl von Edges und Faces zu exportieren und nicht das ganze Shape.
Hmm...
Vielleicht erst aus der Selektion ein neues Shape erzeugen....
Spricht da irgendwas dagegen?
(Gesprochen in "schlechtem" Pseudocode)
Also gegen: getSelectionEx()[0] -> erzeuge Shape -> exportiere Shape -> importiere Shape -> meineEdges = Shape.Edges
Re: Export und Import von Objekten
Das Einfachste ist, Du erzeugst ein Part.Compound und steckst alle Shapes dort rein. Da das Compound auch ein Shape ist, kannst Du es mit exportBrep speichern. Wenn Du es später wieder lädst, brauchst Du nur die Sub-Elemente nehmen, die direkt im Compound liegen.
Re: Export und Import von Objekten
Sehr gut, so werde ich es versuchen.
Vielen Dank euch beiden!!
Vielen Dank euch beiden!!
Re: Export und Import von Objekten
Also pickle wird in absehbarer Zeit nicht funktionieren. Das Hauptproblem ist, dass Objekte von Typ "Part.Solid" behaupten ihr Typ hätte den Namen "Part.TopoShape". Selbst wenn man TopoShape=Shape setzt, passen die Typinformationen nicht und pickle verweigert, zurecht, die Serialisierung. issue #1948
Re: Export und Import von Objekten
Das kommt daher, dass es nur eine zugehörige C++-Klasse TopoShape gibt, die für alle Python-Binding-Klassen genommen wird. Und beim Erstellen der Python-Typen wird der Name der C++-Klasse verwendet. Um das zu beheben, bräuchte man nur im Nachhinein die Typennamen entsprechend ändern.Das Hauptproblem ist, dass Objekte von Typ "Part.Solid" behaupten ihr Typ hätte den Namen "Part.TopoShape".
Re: Export und Import von Objekten
Was heißt den hier genau Nachhinein?wmayer wrote:Um das zu beheben, bräuchte man nur im Nachhinein die Typennamen entsprechend ändern.
Folgende Zeilen in src/Tools/generateTemplates/templateClassPyExport.py schrecken mich davon ab, das anzufassen.
Code: Select all
(WM 2008-10-27 248) "@self.export.Namespace@.@self.export.Twin@", /*tp_name*/
(WM 2009-01-14 623) get@self.export.Twin@Ptr()->unref();
(WM 2007-11-27 772) @self.export.TwinPointer@ *@self.export.Name@::get@self.export.Twin@Ptr(void) const
Re: Export und Import von Objekten
Nein, hier sollte nichts angefasst werden, da das weitreichende und nicht direkt absehbare Folgen haben kann.
Der Trick, den ich meine, ist recht einfach. In AppPart.cpp werden die ganzen Typen im Python-Interpreter registriert:
Um einen einen passenden Namen zu setzen, schreibt man einfach:
Der Trick, den ich meine, ist recht einfach. In AppPart.cpp werden die ganzen Typen im Python-Interpreter registriert:
Code: Select all
Base::Interpreter().addType(&Part::TopoShapeVertexPy ::Type,partModule,"Vertex");
...
Code: Select all
Part::TopoShapeVertexPy::Type.tp_name = "Part.Vertex";
Re: Export und Import von Objekten
Cool, ich hatte echt nicht damit gerechnet, dass das funktioniert. Pull-request ist schon rauswmayer wrote:Code: Select all
Part::TopoShapeVertexPy::Type.tp_name = "Part.Vertex";