Generator and Cloner

  • On 31/01/2013 at 14:32, xxxxxxxx wrote:

    Hy there,

    I created a spline cacher, which is a Python Generator object. It uses the GetContour(..) overwrite to return a spline. The spline gets created by a cache, which is read dependent on the documents time. The document I use is the one given as an argument to the GetContour(..) callback.

    Now, this all works fine, except it can't be used in a cloner:

    File "AoB-SplineCacher.pyp", line 328, in GetContour
      frame = doc.GetTime().GetFrame(doc.GetFps())
    ReferenceError: The object 'c4d.documents.BaseDocument' is not alive.

    How do I need to handle the document, so the Spline Generator will also work within a cloner?

    Thank you,

  • On 01/02/2013 at 01:54, xxxxxxxx wrote:

    Hi maxx,

    This may be an issue with GetContour() because the document passed should be always valid.
    I'll ask the developers if there's a special case if a generator is used in a cloner.

    But it seems some calls return a valid document and others no. You can filter the dead document with:

    if doc() is not None:
        print doc
        print "Dead document"

    doc() invokes doc.__call__() (see the documentation of C4DAtom.__call__()) to know if the document is alive or not.

  • On 01/02/2013 at 09:08, xxxxxxxx wrote:

    Hy Yannick,

    thank you for the hint about testing the doc. The problem seems to go away, if I use the same logic in the GetVirtualObjects method. But then the splines can't be rendered by hair.

    The cloning is not working, if I just check if the doc is alive. Anything else I could try?


  • On 01/02/2013 at 11:50, xxxxxxxx wrote:

    The passed BaseDocument is NULL sometimes in C++ when the object is cloned in a Cloner
    object. It works eg. for the Array-Object. That the passed document can be NULL is not stated in
    the C++ docs, nor I think this is intended?

    The Python issue might be due to the fact that the Python wrapper assumes the document may
    never be NULL and wraps a NULL pointer being passed to Python.

    I reported this as a bug.

     \* Copyright (C) 2013, Niklas Rosenstein
     \* All rights reserved.
    #include <c4d.h>
    class SplineCacheData : public ObjectData {
        static NodeData\* Alloc() { return gNew SplineCacheData; }
        /\* Overrides: ObjectData \*/
        SplineObject\* GetContour(BaseObject\* op, BaseDocument\* doc, Real lod,
                BaseThread\* bt) {
            if (!doc) {
                GeDebugOut("WARNING: No document passed on GetContour()");
                return NULL;
            LONG frame = doc->GetTime().GetFrame(doc->GetFps());
            String name = doc->GetDocumentName().GetString();
            String message = "GetContour() Document name: " +
                             doc->GetDocumentName().GetString() + ", frame: " +
            return NULL;
    Bool PluginStart() {
        return RegisterObjectPlugin(
            1000002, "Spline Cache Test", OBJECT_ISSPLINE, SplineCacheData::Alloc,
            "", NULL, 0);
    Bool PluginMessage(LONG type, void\*pData) {
        return TRUE;
    void PluginEnd() {


  • On 02/02/2013 at 05:18, xxxxxxxx wrote:

    Thanks Niklas, for the C++ Test-Case...


  • On 05/02/2013 at 03:39, xxxxxxxx wrote:


    For each clone no document is passed to GetContour() and op.GetDocument() gives None.
    But yes there's an issue in Python that it gives a dead document instead of a None.

    I think you better get the current frame overriding Execute() and caching it.

  • On 13/02/2013 at 17:34, xxxxxxxx wrote:

    Ok, will do so...


Log in to reply