ImportLDraw
ImportLDraw copied to clipboard
Add consumption of blender instancing instead of linked duplicates
When working with large files (58k bricks) it takes a long time (~1h) to duplicate all the bricks. Additionally once the model is loaded into the scene it is almost impossible to navigate the scene or do any actions in the scene. This is most likely related to the large amount of memory the model takes up (~15gb ram). While using instancing the memory consumed is far less (~300mb) and performance is very acceptable (realtime).
The largest drawback of using instancing is that blender documentation does not clearly describe how faces are being used to calculate the orientation of the objects. With this code the vertex order is done in such a manor that the angle of the object being duplicated is not changed allow the normal matrix to be applied and created the correct translation for the object.
When modifying the model it is possible to show the faces and move them in modeling mode. Adding additional instances of a part requires just duplicating one of the faces. This is some overhead for making adjustments in blender, but the changes enable enough performance to actually interact with the model. As this change also makes the import way faster (<1 min) it is possible to just make adjustments to the model in the source program and importing the file again.
I am not very familiar with the whole code line and blender APIs. There for some cleanup and adjustments will still be required to make this a viable feature.
The large memory usage and slow performance does appear to be due to the modifiers added to each linked duplicate. A workaround is to untick both 'Smooth faces and edge-split' and 'Bevel edges', which results in no modifiers but a usable interface and faster rendering.
Note that turning off every modifier's visibility for viewport rendering allows for less memory and faster editing, but still has larger memory and slower when actually rendering.
I am a little reluctant to head down the path of vertex / face instancing, because it would make editing the scene less easy/intuitive.
One possibility that I've not tried yet is to use Collection Instancing. Each lego part+colour along with its modifiers would be its own collection, and this collection gets instanced for each time that part is used. The hope is that this should result in way fewer modifiers, so ought to reduce memory use, and ideally result in better viewport and rendering times as well? It's a little hard to say without actually trying it.