Dear Ferdinand,
thank you so much for your quick and helpful reply! Amazing how fast, super impressive and it really motivated me to keep going. I needed a bit more time to reply and verify I am not writing stupid things. I can't promise that there is nothing stupid left, but I did my best :)
Before creating your next postings, we would recommend making yourself accustomed with our forum and support procedures. You did not do anything wrong, we point all new users to these rules.
This makes a lot of sense. I checked out the links you posted and found already the one or other thing I want to do better.
To clarify, this is my main question:
How can I search in a GLTF-file for specific objects, and load them selectively in the scene - without loading the whole file in memory?
I have a gltf-file with hundreds of shapes, possibly gigabytes. They are structured like a flat database. Imagine it like a 3D font, with many, many individual letters. I don't want the whole character set for all languages and variations to be loaded, just because the user wants to write "hello world". It is by the way, exactly what this is going to be used for and will become relevant when we think about identifiers.
Maybe it is best to give an example of what I want to do:
- parse the nodes-index of the gltf-file
- find an object by name
- load this particular object in memory
- instantiate object in the scene
1) parse the nodes-index of the gltf-file
Consider this gltf-file, which holds various objects:
{
"meshes": [ ... ],
...,
"nodes": [
{
"mesh": 0,
"name": "Eberhardt"
},
{
"mesh": 1,
"name": "Edeltraudt"
},
{
"mesh": 2,
"name": "Ebertraudt"
},
...,
{
"mesh": 65535,
"name": "Eberhardt42"
},
]
}
So here I want to parse "nodes", check the names and only load the meshes of the nodes that start with "Eberhardt".
2) find an object by name
I agree that names are usually not a good identifier. However, in this case it does make sense to me, because the individual nodes are characters for a 3D font. The first character of the string refers to the character the shape represents. "A_1"
, "A_2"
, "Γ_42"
, "δΊΊ_1"
or "π_9"
can all be represented in json/gltf strings, which makes the name easy and straightforward to use. It doesn't matter if a character has the name "A_1.001"
or "A_1"
About your First Question
You can search for objects with c4d.documents.BaseDocument.SearchObject.
Maybe this is due to my limited understanding, but I couldn't manage yet to use it without loading the whole document in memory. Also, as described above I need to allow partial matches and it looks as if SearchObject
only searches for exact matches. I realize that I didn't mention this limitation in my initial question...
Apart from the fact that names are a poor way to identify objects, you can also not find multiple objects with the same name in this manner. With release 2025 we added abstracted scene iteration.
The abstracted scene iteration looks great! However, I need to stay compatible with 2024.x.x
.
Last but not least, what you are doing in your example code, recursion (at least unbound recursion) should be avoided, as this can quite easily lead to stack overflows. See this thread for how to do scene traversal manually.
Noted and agreed. Thank you for your attentiveness! Also, a wonderfully helpful post in that thread. Isn't this a perfect 2024.x.x
replacement for what I'd use mxutils.RecurseGraph
in 2025.x.x
for?
such as:
for n in GetAllNodesIteratively(node):
if n.GetName().startswith("Eberhardt"):
pass
I guess the only real downside is that mxutils.RecurseGraph
would be implemented in c++ and way more performant on large node graphs.
3) load this particular object in memory
Ideally we have identified the matching nodes, without loading the whole gltf into memory. But we do need to load the matches selectively. I do not know yet how to do that, or if this is even possible with out-of-the-box functions. If we can manage to do 1)
and 2)
, then this should be possible somehow. In any case I'd love to use existing functions and avoid custom acrobatics wherever possible.
4) instantiate object in the scene
I realize also this may be a follow up question, but I guess it will lead me to c4d.InstanceObject and should be trivial in comparison.
I hope that my question makes sense, and thank you so much already for your help.