Open morawi opened 4 years ago
It does already load from cached files if they exist and the cache
parameter is True
@einarf that's totally correct, but I would like to use those streams in my application (stream of bytes and not as a file); in fact, I would like to store them in a single file with some other data; then when I read the file I would like to construct the OBJ from those streams. One way to do this is to load those BIN
and JSON
file and store them into my file, then, at the time of loading; save them as BIN
and JSON
files and construct the object with cache=True
, but that would be cumbersome.
Anyways, could you please guide me where in the code the loading happens? Maybe I can tweak it to my case.
I don't think you can fully reconstruct the obj from the bin/json file. They are mainly made so users can easily dump them into graphics memory.
I do have a library overriding the cache loader that just uploads the byte streams directly to the gpu instead of reconstructing the obj itself (much faster) https://github.com/moderngl/moderngl-window/blob/4c3cd385718517a8055e8c271195f9100eaf2a66/moderngl_window/loaders/scene/wavefront.py#L52-L69
Cache loading triggers from this : https://github.com/pywavefront/PyWavefront/blob/caa2013d7026dd484ac8c5ca8273f2d680196130/pywavefront/obj.py#L86-L90
Loader and saver is here : https://github.com/pywavefront/PyWavefront/blob/master/pywavefront/cache.py
What I wanted is to pass data
instead of reading it via data = json.loads(fd.read())
(line 193) and other info red via file handler fd = gzip.open(str(cache_name(self.file_name)), 'rb')
(lines 109-119) to the class constructor, but I guess that would disrupt the integrity of PyWavefront.
Hence, the best way to do this by allowing my application to save the cached files (BIN and JSON), same for the .mtl
file if used, before calling PyWavefront (I am thus removing the original .obj
file, and). I did a few tests and it worked even after xx.obj
file has been removed, as long as cache=True
and xx.obj.bin
and xx.obj.json
are available.
Yup. that seems reasonable. You can even replace the cache loader / saver classes here if you need more flexibility : https://github.com/pywavefront/PyWavefront/blob/caa2013d7026dd484ac8c5ca8273f2d680196130/pywavefront/obj.py#L50-L51
To make things future proof I would check the version in the json file. I had plans to extend this feature by adding pre-computed bounding boxes for example, but that might not break compatibility.
Thanks you for the heads up! I don't think I need to do this now, but maybe later.
The only concern, although trivial, is that when the original file OBJ
is cached and then removed, one still needs to use its name when constructing the wavefront .. i.e. via
pywavefront.Wavefront('earth.obj', ...)
Not sure if it would be a good practice to remove the .obj
extension from the name, and then to be added later inside Wavefront
class if it is not there. In this case, as an example with earth file, one can either use,
pywavefront.Wavefront('earth', ...)
or
pywavefront.Wavefront('earth.obj', ...)
to construct the object.
I would like to read the generated
BIN
andJSON
(when cache=True) directly via simple function into a Wavefront object. That is, I would like to read these two files myself and feed them to Wavefront constructor. I wonder if this can be done via some auxiliary function?