Loading geometry directly from memory

Hello,
I am trying to figure out how to load geometry with python into TD without using files on disk. I would like to use raw byte data in memory to construct the geometry. I have seen some nice functionality in ObjectCOMP Class ( importABC, importFBX ), however this seems to support only loading files from disk.

Please what would be a preferred way on how to approach this (ideally with lowest performance overhead possible)? Thanks. :slightly_smiling_face:

Perhaps easiest would be to install RAM drive software on your machine, and load your assets from there.

Another hack could be to lock the SOP nodes and save them out as a .tox file.
Because in the release notes of the official 2021 release I see these new methods:

COMP Class - New methods saveByteArray() and loadByteArray() for saving and loading .tox files directly to and from memory.

Thanks, RAM drive software sounds interesting, but it seems a bit more complex in terms of setup than I could use with this specific application. This would definitely work, but it would be best if it could run without external dependencies.

I should have mentioned that I am receiving dynamic geometry data using network and that’s why I would like to directly construct raw bytes into geometry representation. Therefore I can’t use saveByteArray() and loadByteArray() - even though these two seem to be a pair of very useful new fellas :slightly_smiling_face:.

I was thinking about using Script SOP where I would manually construct geometry from some simple format like .obj… However this might require quite a lot CPU time with large geometries, so it isn’t ideal. Maybe I could wrap this inside of Engine COMP to separate it from main thread. I am not sure if this is the right approach, maybe there is a better way to load such data from memory?

If Python is too slow, probably a Custom SOP operator could do this, if you feel like brushing off your C++ skills

I think it would be a very valid RFE to support loadByteArray() for all fileIn OPs (or any place where we can load from disk )

Yeah, this would be a way to go. However I would still have to use the python to process data received in TCP DAT - feed them into something like Table DAT (that could be then passed into custom C++ operator). I am not sure if this wouldn’t eventually propose similar performance to using Script SOP.

I guess I would first try to get this going using python so I can see how long will the processing take. Based on that I will consider using some custom op to speed things up. Thanks for ideas :slightly_smiling_face:

This would be really amazing - very flexible. I will move this thread into RFE section :slightly_smiling_face:

You can put your bytearray into VFS, and then reference that from any file parameter.
https://docs.derivative.ca/Virtual_File_System

2 Likes

Ahaa, that is perfect, thank you very much for information :slight_smile:

I have eventually realized that using standard file formats isn’t the best approach due to them having larger data size than was necessary. Therefore I have decided to transfer geometry in custom (very simple) form (just points + face vertices - packed with lowest possible size).

This works fine, I can construct numpy arrays from such data (coming trough TCP/IP DAT) very fast.
points = np.frombuffer(bytes, dtype=np.float32)
tris = np.frombuffer(bytes, dtype=np.int32)

However I am wondering what would be the fastest way of constructing actual geometry from such numpy arrays? I have tried Script SOP but it doesn’t perform well with large meshes. Same thing applies for approach where I have first written these arrays to DATs → which were then used to construct geometry in DAT to SOP. (This also didn’t perform well with more complex meshes.) I have thought this might be a perfect situation for Engine COMP, but since it doesn’t provide SOP output at the moment, I would still have to output DAT → convert it into SOP in main scene, which wouldn’t really help me in terms of performance.

I am not sure if Custom OP would help in this matter as I feel like I would still have to first write numpy arrays from python into something like DAT - which wouldn’t perform much better.

If someone knows some fast approach for getting these numpy arrays into actual geometry I would be thankful :slightly_smiling_face:

P.S. I have moved this to General section as it is no longer a RFE.

How much of a file-size difference is there between your own construction and the actual filesize and is it really that important? Just wondering if it might not be faster to simply save the geometry out, transfer the file and afterwards load it in via fileInSOP.
I just suppose that you will still have the problem of getting a hickup when loading the file.

It is quite a lot actually - so far it seems that on the sending side of this setup I am only able to create .OBJ files (I guess it would be different situation with something like .USDZ, but it is not my case at the moment).

Since OBJ stores data as plain text by design, this comes down to text representation of float values. Float is normally stored as 4bytes, but when stored as ASCII it needs around 8bytes (if we assume 7 significant digits + dot character “.”). So for large array of points (each described by 3 floats) this actually doubles the size.

Indeed that is quite alot.
How much control do you have on the senderSide of things? You could use ZLIB to compress the OBJ file, transfer it and decompress it again in touch. Then, on the receiver you could even use a yielded per-frame decompress of the received data. But this begs the question if the connection between sender and receiver is so slow that it is actually neccesarry.

I have thought of using compression, but in this particular case it introduces unwanted performance overhead on the sender side. Mesh sending is performed multiple times in a second (sending quite a lot of data) and the sender device is already at its CPU peak (and running quite hot). Performing additional compression would result in overheating and would render this process most likely unstable…

They are not particularly slow, but the amount of mesh being sent is quite large and I have figured it would be best to lower network requirements (especially due to the fact I am using wifi for this setup :slightly_smiling_face:) by sending it in smallest possible form…

A Custom SOP would do it, but you’d need to get familiar with Python and Numpy in C code to be able to read from your Numpy arrays directly in the C++ code.

Thanks @malcolm, this sounds very good. I will look into it. In case you would happen to know about some good info / docs / articles on this topic please let me know. Thanks. :slightly_smiling_face: