Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    Document copied for Picture viewer doesnt copy contents of child of a TagData

    Cinema 4D SDK
    c++
    3
    4
    60
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • E
      ECHekman
      last edited by ECHekman

      I am encountering a problem when rendering to picture viewer.
      I have two plugins, a TagData and a NodeData as its child.
      I also created a link from the TagData to the NodeData for easy access
      However when the document is copied and sent to the picture viewer renderer there are two issues.

      1. The link is not copied
      2. The contents of the NodeData basecontainer are not copied over

      The copied TagData does have a child object with my type, so it does exist

      Here is how I connect the two plugins

      Bool MyTagData::Init(GeListNode* node, Bool isCloneInit)
      {
          BaseTag* tag = (BaseTag*)node;
          BaseContainer *data = tag->GetDataInstance();
          BaseList2D* mynodedata= BaseList2D::Alloc(ID_MY_NODEDATA); // Creating my MyNodeData
          mynodedata->InsertUnderLast(node); //Add as mynodedata as a child to mytagdata
          data->SetLink(MYTAG_NODEDATA_INK, mynodedata); //Add link for easy access
          return true;
      }
      

      This basically works in all situations, except when sending it to the picture viewer for rendering.
      I feel like im missing something, but i cant find what in the documentation

      1 Reply Last reply Reply Quote 0
      • M
        m_adam
        last edited by

        Hey you are not supposed to modify the scene graph during the init function.
        Adding children to a tag while it may be possible is as far as I know not something done in Cinema 4D. so for optimization purpose I would not be surprised that they are never copied at all.

        With that's said I would recommend you to use a custom branch to store your BaseList2D as demonstrated in C++ SDK: Custom Branching Code Example .
        In last case you should implement the CopyTo to properly copy your data when your node is copied. But again modifying the scene Graph during the Init is not the way to got.

        Cheers,
        Maxime.

        MAXON SDK Specialist

        Development Blog, MAXON Registered Developer

        1 Reply Last reply Reply Quote 0
        • E
          ECHekman
          last edited by

          Thanks for your reply m_adam

          Thanks for providing the information that the init function should not modify the scene graph. Ill take this into account in the future.

          I went through that example you linked, but Im a bit unclear why it is nessesary to manually create the handling of a custom and parallel nodegraph branch when plugin GeListNodes are already graphs themselves?

          ferdinandF 1 Reply Last reply Reply Quote 0
          • ferdinandF
            ferdinand @ECHekman
            last edited by ferdinand

            Hello @ECHekman,

            Thanks for providing the information that the init function should not modify the scene graph. Ill take this into account in the future.

            It is not only NodeData::Init but the majority of NodeData methods and the methods of derived classes that cannot modify the scene graph of a loaded document, as for example the scene graph they are attached to. The reason is that such methods, as for example NodeData::Init, TagData:Execute, ObjectData::GetVirtualObjects, and many more, run in their own threads to parallelize scene execution. Modifying the scene graph of a loaded document from a non-main-thread (i.e., parallel) context can lead to race conditions and access violations and are therefore strictly forbidden. Forbidden are primarily allocations and deallocations, parameter get/set access is allowed (as long as it does not allocate or deallocate a pointed object) but also discouraged outside of TagData::Execute. For details, see Cinema 4D Threads Manual.

            I went through that example you linked, but I' m a bit unclear why it is necessary to manually create the handling of a custom and parallel nodegraph branch when plugin GeListNodes are already graphs themselves?

            I am not quite sure how you mean 'parallel', but a GeListNode implements both hierarchal (i.e., tree) relations with InsertUnder, GetUp, GetDown, GetNext etc. and arbitrary (i.e., graph) relations with GetBranchInfo. The hierarchy of a node type, e.g., Obase - a BaseObject or Tmytag - your tag class, are always meant to be of the same type and follow the conventions of their base class. Tags are not meant to have children. You must implement your own branch to declare your own non-hierarchical relation between your plugin tag and your basic node.

            ⚠ The workaround Maxime suggested, just implementing NodeData::CopyTo is unfortunately not valid.

            First of all, you must always implement all three serialization functions Read, Write, and CopyTo, you can never only implement only one of them.

            But storing nodes irregularly in this manner can lead to access violations as Cinema 4D is then not aware that this quasi-branch exists and might try to execute multiple things at once (via NodeData::GetAccessedObjects), leading to read/write access violations. Moreover, I am fairly sure that this might lead to event or call starvation when Cinema finds there such a dangling BaseList2D (NodeData) instance under your BaseTag (TagData). Or even worse, it will ignore completely it in some contexts, because tags are not supposed to have children.

            You must implement a branch in your case, I would recommend following the SDK example as it is slightly cleaner than the forum preview Maxime linked to.

            Cheers,
            Ferdinand

            MAXON SDK Specialist
            developers.maxon.net

            1 Reply Last reply Reply Quote 0
            • First post
              Last post