Hello @interfaceguy,
Thank you for reaching out to us. Please open a new topic for new questions as lined out in our Forum Guidelines: Rules of Conduct. This is not a follow up question to your initial question. I have forked your question, for future cases we might refuse to answer your questions when this rule is not followed.
About your question, the following statement is not true:
calling the reload button and c4d.EventAdd() which makes the hierarchy containing the spline visible in the GUI, C4D does not recognize that the vector_import object now has children.
Invoking the button and EventAdd
will not build the caches for your object. It is only after your script has ended that Cinema 4D will do that automatically for you. Which is probably why you came to that conclusion, but when you call GetDown()
on your vector_import
, it still has no children. You must execute the passes on an object/document when you want to access/build the caches of it immediately after a parameter change or when the object has been newly instantiated.
Find an example at the end of this posting.
Cheers,
Ferdinand
The result:

The code:
"""Simple example for evaluating the cache of a generator.
"""
import c4d
import typing
doc: c4d.documents.BaseDocument # The active document
op: typing.Optional[c4d.BaseObject] # The active object, None if unselected
def AssertType(item: any, t: typing.Union[typing.Type, tuple[typing.Type]], lbl: str) -> any:
"""Asserts #item to be of type #t.
When the assertion succeeds, #item is passed through, otherwise a type error with #lbl referring
to #item is being raised.
"""
if not isinstance(item, t):
raise TypeError(f"Expected item of type '{t}' for '{lbl}'. Received: {type(item)}")
return item
def main() -> None:
"""
"""
# Instantiate the vector import object.
node: c4d.BaseObject = AssertType(c4d.BaseObject(1057899), c4d.BaseObject, "node")
# Due to a bug in the vector import object, Cinema 4D will crash when attempting to write the
# ART_FILE parameter without the node being attached to a document. Normally we would set here
# this parameter, as this would make more sense, now it has been moved to line 44 for this
# reason.
# The node #node has now no caches, i.e., the generator has not run yet and no amount of button
# clicking and EventAdd() will change that. We must build the caches by executing the passes
# on #node. For that #node must be part of a document. We could insert #node into the active
# document and execute the passes there, but this has two drawbacks:
#
# 1. This cannot be done in any non-main thread context, as it might then crash Cinema 4D.
# 2. This can also be slow, as it will also revaluate everything else which is in the active
# document.
#
# So, we are going to do this in a temporary document.
BaseDocument = c4d.documents.BaseDocument
temp: BaseDocument = AssertType(BaseDocument(), BaseDocument, "temp")
temp.InsertObject(node)
# Set the parameter for the file.
node[c4d.ART_FILE] = "E:\myFile.svg"
# Build all caches in the document.
temp.ExecutePasses(
bt=None, animation=False, expressions=False, caches=True, flags=c4d.BUILDFLAGS_NONE)
# Node now has a cache, and also its hierarchy would be populated if we had set
# ART_SHOW_HIERARCHY to True. But we can also just reach into the cache now when we want
# to access the output of the generator. We can also remove #node now from the temporary
# document, as the cache is bound to the node itself. We also must do this if we want to
# insert #node into another document (or return it in a GVO method), as a node can only
# be part of one document.
node.Remove()
# Get the cache.
cache: c4d.BaseObject = AssertType(node.GetCache(), c4d.BaseObject, "cache")
print (f"{cache = }")
# Some like this should never be done, as every step in this chained function call can return
# a null-pointer, i.e., None in Python.
# spline = vector_import.GetDown().GetDown().GetDownLast()
# Get the sort of thing you wanted to get. It is in general not safe to navigate hierarchies in
# this predetermined manner but this will at least not stop your code when the assumption
# fails inevitably.
if cache.GetDown():
cache = cache.GetDown()
if cache.GetDown():
cache = cache.GetDown()
if cache.GetDownLast():
cache = cache.GetDownLast()
# Do stuff with this part of the cache.
if isinstance(cache, c4d.PointObject):
for p in cache.GetAllPoints():
print (p)
# When we wanted to insert this part of the cache into the active (or any other) document, we
# must clone it first.
clone: c4d.BaseObject = AssertType(cache.GetClone(c4d.COPYFLAGS_0), c4d.BaseObject, "clone")
# Insert both the generator and a copy of a part of its cache.
doc.InsertObject(node)
doc.InsertObject(clone)
c4d.EventAdd()
if __name__ == '__main__':
main()