How to LoadDocument from string in memory? π€
-
I have a Adobe Illustrator file contents generated by code not saved in a disk. Now i need to import it into Cinema 4D as a document. Is it possible open in Cinema 4D data not from file but from memory?
Found some SDK examples here but have no idea how to save text data to c4d.storage.MemoryFileStruct correctly to open it with LoadDocument after that.
Here is my .ai file code example:%!PS-Adobe-3.0 %%BoundingBox: 0 0 330 700 %%Pages: 1 %%EndComments 0 setgray 0 setlinecap 1 setlinewidth 0 setlinejoin 10 setmiterlimit [] 0 setdash %%EndProlog %%Page: 1 1 newpath 81 387 m 80 384 80 382 81 381 c 82 379 84 379 88 379 c 151 379 l 154 379 156 379 157 381 c 158 382 158 384 158 387 c 151 635 l 151 637 150 639 149 640 c 148 641 146 642 144 642 c 95 642 l 92 642 90 641 89 640 c 88 639 88 637 88 635 c 81 387 l 177 0 m 171 0 169 2 169 7 c 161 314 l 160 318 157 321 153 321 c 86 321 l 81 321 79 318 79 314 c 70 7 l 70 2 67 0 62 0 c 17 0 l 14 0 12 0 11 2 c 10 3 10 5 10 8 c 27 615 l 27 645 34 666 48 680 c 62 693 84 700 114 700 c 125 700 l 155 700 176 693 190 680 c 204 666 211 645 212 615 c 229 8 l 229 5 228 3 227 2 c 226 0 224 0 222 0 c 177 0 l closepath stroke %%Trailer
Thx!
-
Hi @mikeudin,
Although MemoryFileStruct is a little outdated variant of our in-memory file system, this is the only option to be used in Python API. If using C++ please use RamDiskInterface instead!
MemoryFileStruct is sort of a wrapper over a bytes buffer that the Filename object can point to and hence use it in other parts of our API. This actually means, that similarly to a normal file you can store any data inside and use it as if it was a real file on a disk.
HyperFile class gives you access to some convenient functions for storing different types of data. Normally writing and reading functions of the HyperFile add some meta information to the file or to these chunks of data that you store (one of this extra pieces of info is for example "indent", the identification number that you can use to check that the file you're reading was created by your plugin, or may be by the correct version of your plugin).
In case of Adobe Illustrator file you already have the entire content of the file that you need to put inside the MemoryFileStruct. For that you don't even need HyperFile functions, you just need to convert your string to the bytearray and initialize MemoryFileStruct that points to this bytearray.
The LoadDocument function allows you to use MemoryFileStruct instead of filename, so you just use it in a normal way.
Please check the code snippet below, that shows the described approach.
Cheers,
Iliaimport c4d AI_CONTENT = """%!PS-Adobe-3.0 %%BoundingBox: 0 0 330 700 %%Pages: 1 %%EndComments 0 setgray 0 setlinecap 1 setlinewidth 0 setlinejoin 10 setmiterlimit [] 0 setdash %%EndProlog %%Page: 1 1 newpath 81 387 m 80 384 80 382 81 381 c 82 379 84 379 88 379 c 151 379 l 154 379 156 379 157 381 c 158 382 158 384 158 387 c 151 635 l 151 637 150 639 149 640 c 148 641 146 642 144 642 c 95 642 l 92 642 90 641 89 640 c 88 639 88 637 88 635 c 81 387 l 177 0 m 171 0 169 2 169 7 c 161 314 l 160 318 157 321 153 321 c 86 321 l 81 321 79 318 79 314 c 70 7 l 70 2 67 0 62 0 c 17 0 l 14 0 12 0 11 2 c 10 3 10 5 10 8 c 27 615 l 27 645 34 666 48 680 c 62 693 84 700 114 700 c 125 700 l 155 700 176 693 190 680 c 204 666 211 645 212 615 c 229 8 l 229 5 228 3 227 2 c 226 0 224 0 222 0 c 177 0 l closepath stroke %%Trailer""" def main(): contentBytes: bytearray = bytearray(AI_CONTENT.encode(encoding='utf-8')) mfs = c4d.storage.MemoryFileStruct() mfs.SetMemoryReadMode(contentBytes, len(contentBytes)) loadedDoc = c4d.documents.LoadDocument(mfs, c4d.SCENEFILTER_OBJECTS | c4d.SCENEFILTER_MATERIALS) if loadedDoc is None: raise RuntimeError('Failed to load document!') c4d.documents.InsertBaseDocument(loadedDoc) c4d.documents.SetActiveDocument(loadedDoc) if __name__ == '__main__': main()
-
Cool! Thank you!