Change BaseContainer ID

On 22/02/2018 at 09:40, xxxxxxxx wrote:

Hi guys,

I'm trying to change the ID of a container, is there a good way of doing it please? I've tried using the .GetId() and .SetID() functions without any success. So I am probably using it incorrectly or there is a way of doing this by copying the container and removing the original one perhaps?

Here's some test code:

import c4d
from c4d import gui
#Welcome to the world of Python
  
  
def main() :
    doc = c4d.documents.GetActiveDocument()
    docBC = doc.GetDataInstance()
    
    for id, value in docBC:
        
        if id == 12345:
            docBC.RemoveData(id)
        
        print id, value
    print "---------------------------------\n"
       
    MAINBC = c4d.BaseContainer()
    docBC.SetData(12345, MAINBC)
    subBC = c4d.BaseContainer()
    
    for i in range(0, 10) :
        MAINBC.SetData(i, subBC)
    
    for id, value in MAINBC:
        if id > 5:
            print id, value
  
    print "---------------------------------\n"
  
if __name__=='__main__':
    
    main()

The idea is to change the id for the baseContainers to ID - 1.

Hopefully this will make sense, but let me know if you need more info.

Thank you in advance! 🙂

Andre

On 23/02/2018 at 08:57, xxxxxxxx wrote:

Hi Andre,

first of all there's a difference between the ID of a BaseContainer (GetId(), SetId()) and the IDs used for the stored data (e.g. SetData(id, data)). The ID of the BaseContainer itself can be used to easily identify a container. For example you could set the ID of your MAINBC to a unique plugin ID.

By the way, when storing something in Cinema 4D's BaseContainers (like in this case the document settings), you should use a unique plugin ID to store your custom container, to make sure, you don't collide with anything else.

Then there's something special about the settings of a document. These are a bit distributed, so you'd rather use GetDocumentData(), SetDocumentData() and/or GetSettingsInstance() instead of doc.GetDataInstance().

And then there's the part of your question about setting a container's ID to -1. I'm not sure, if you are talking about the container ID or some ID of the contained data, nor do I see, where you try to do this in your code. Maybe you can explain a bit more, what you are actually trying to achieve?

Even though it's in our C++ SDK documentation and only contains C++ code snippets, I think, the BaseContainer manual could also help to get a better understanding.

On 26/02/2018 at 00:22, xxxxxxxx wrote:

Hi Andreas,

Thank you for your help!

first of all there's a difference between the ID of a BaseContainer (GetId(), SetId()) and the IDs used for the stored data (e.g. SetData(id, data)). The ID of the BaseContainer itself can be used to easily identify a container. For example you could set the ID of your MAINBC to a unique plugin ID.

By the way, when storing something in Cinema 4D's BaseContainers (like in this case the document settings), you should use a unique plugin ID to store your custom container, to make sure, you don't collide with anything else.

Fantastic! 🙂
To be honest I am using the unique PLUGIN ID, what I wrote was just as an example. But the idea is similar.

Then there's something special about the settings of a document. These are a bit distributed, so you'd rather use GetDocumentData()SetDocumentData() and/or GetSettingsInstance() instead of doc.GetDataInstance().

Ah ok! I see... In the examples that I saw through the forum I saw the doc.GetDataInstance(), thinking that it would be the best way to go. Appreciate you pointing it out!

And then there's the part of your question about setting a container's ID to -1. I'm not sure, if you are talking about the container ID or some ID of the contained data, nor do I see, where you try to do this in your code. Maybe you can explain a bit more, what you are actually trying to achieve?

Apologies! That's my bad, as I didn't explain myself correctly.
I'm trying to change the id of the contained data.
In the example I've added, the MAINBC will contain 10 pieces of data with ID from 0 to 9.
What I like to do is if I remove one of values of the contained data, the ID values that are bigger than the ID removed be subtracted by 1.
If the data with ID 5 is removed, then:
6 <c4d.BaseContainer object at 0x0000000021858260>
7 <c4d.BaseContainer object at 0x00000000218585A8>
8 <c4d.BaseContainer object at 0x00000000218583E8>
9 <c4d.BaseContainer object at 0x0000000021858420>

will become:
5 <c4d.BaseContainer object at 0x0000000021858260>
6 <c4d.BaseContainer object at 0x00000000218585A8>
7 <c4d.BaseContainer object at 0x00000000218583E8>
8 <c4d.BaseContainer object at 0x0000000021858420>

Hopefully this will make more sense! 🙂

Even though it's in our C++ SDK documentation and only contains C++ code snippets, I think, the BaseContainer manual could also help to get a better understanding.

Thank you! Will have a look!

I appreciate your time helping me out. 😉

Andre

On 26/02/2018 at 02:22, xxxxxxxx wrote:

Well, as long as the data type stored at a given ID does not change, it could be as easy as this:

    # first overwrite, beginning with the "to be removed ID" all entries with the following one
    for i in xrange(idRemove, idMax-1) :
        bc[i] = bc[i+1]
    # finally remove the, now duplicate last entry with last ID
    bc.RemoveData(idMax-1)

On 26/02/2018 at 02:33, xxxxxxxx wrote:

Ahhh! I see what you did. Fantastic!

That gives me a better insight on how to correctly change the container's data.

Thank you very much! 🙂

Have a rest of a great day!

Andre