pyOCCT
pyOCCT copied to clipboard
Methods that take a stream (ie DumpJson) don't work
I'm probably doing this wrong...
from OCCT.gp import *
t = gp_Trsf()
import sys
t.DumpJson(sys.stdout)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-10-653204f5a44e> in <module>
----> 1 t.DumpJson(sys.stdout)
TypeError: DumpJson(): incompatible function arguments. The following argument types are supported:
1. (self: OCCT.gp.gp_Trsf, arg0: std::ostream) -> None
2. (self: OCCT.gp.gp_Trsf, theOStream: std::ostream, theDepth: int) -> None
Invoked with: <OCCT.gp.gp_Trsf object at 0x7f0facf7c170>, <ipykernel.iostream.OutStream object at 0x7f0fb063bac0>
Did you forget to `#include <pybind11/stl.h>`? Or <pybind11/complex.h>,
<pybind11/functional.h>, <pybind11/chrono.h>, etc. Some automatic
conversions are optional and require extra headers to be included
when compiling your pybind11 module.
Expected Behavior
I think that should write to stdout
Current Behavior
Gives the error
Possible Solution
Does including the <pybind11/stl.h> make this work?
this might be relevant? https://pybind11.readthedocs.io/en/stable/advanced/pycpp/utilities.html#capturing-standard-output-from-ostream
and
https://www.opencascade.com/doc/occt-7.4.0/refman/html/_standard___o_stream_8hxx.html
Thanks for the links, looks like Standard_OStream is just a typedef and pybind has a pythonbuf class for this.
I have two ideas, not sure which is best (or if they'll work):
- Change any
std::ostreamfunctions to be lambdas that take a pyobject instead of the ostream, then wrap the object in a pythonbuf. This way would allow just usingt.DumpJson(some_file_like_obj) - Make
Standard_OStreamapy::classthat creates a pythonbuf, so you have to create a Standard_OStream passing the python file like object, then pass the Standard_OStream to the function.
Any preferences? I can try to make a patch.
hmm....my first thought is 2....i think at the moment Standard_OStream is just skipped in the binder https://github.com/LaughlinResearch/pyOCCT/blob/1c354c2ffb92f5c49d0a4f1c7a26a6483c8b2b9f/binder/config.txt#L118
so, seems like if we just bind Standard_OStream...then we just create one in python and existing functions just work? and it follows the OCCT api. otherwise, #1 seems like a case that will require special logic in the binding generator to handle that type and writing the lambdas. which, we could do, but seems like 2 is worth a shot?
In some cases these methods can write to a file so as a workaround I've created a temporary file, used OCCT to write to the file, and then read the file
Did anything happen related to this issue since it was raised? I get similar issues.
Seems that this gist provides a smooth and easy to integrate solution to this problem via custom type casting.
I can confirm that the gist was the way to go, though for me it required some modifications: https://github.com/CadQuery/OCP/blob/master/pystreambuf.h