Populating InExclude description during Init()
-
On 05/12/2014 at 22:01, xxxxxxxx wrote:
User Information:
Cinema 4D Version: 16
Platform: Windows ;
Language(s) : C++ ;---------
Hi guys,I'm trying to do this behavior for my object plugin's object creation:
1. Select input objects in the Object Manager.
2. Create new object (OBJ).
3. place input objects in OBJ's InExcludeList (INEX).Bool OBJ::Init(GeListNode *node){ BaseContainer *bc = ((BaseObject* )node)->GetDataInstance(); BaseDocument *doc = GetActiveDocument(); if(!doc){ return TRUE; } AutoAlloc<AtomArray> selection; if(!selection){ return TRUE; } doc->GetActiveObjects(*selection, GETACTIVEOBJECTFLAGS_SELECTIONORDER); if(selection->GetCount()){ Int64 i, k; k = selection->GetCount(); InExcludeData *inex; inex = (InExcludeData* )bc->GetCustomDataType(INEX, CUSTOMDATATYPE_INEXCLUDE_LIST); for(i = 0; i < k; i++){ inex->InsertObject((BaseList2D* )selection->GetIndex(i), 0); } } return TRUE; }
The problem I'm having is that during the Init() call of OBJ, using (InExcludeData* )data->GetCustomDataType(INEX, CUSTOMDATATYPE_INEXCLUDE_LIST) returns nullptr.
Is there a way to do this inside an object plugin's Init, or is my only option to create a command plugin that creates OBJ and populates INEX after?
-
On 06/12/2014 at 07:25, xxxxxxxx wrote:
I've found the Init() method to be very problematic for things like this.
It seems to work best for setting things like variable values, file paths, and loading textures.
So I only use it as a resource loader...never an object selector or creator.I haven't tried this. So it might not work.
But it sounds a lot like the problem of trying to create things with a tag plugin.
I've found that I have to check if a specific tag or object is selected inside of the Message() method. And then create the new tag or object in there.
Using the Message() method this way is the only way I could find to create things without crashes.But I haven't tried this on an ObjectData plugin.
So it might not work in your case.-ScottA
-
On 06/12/2014 at 07:56, xxxxxxxx wrote:
Init() is definitely not the place to do this. Realize that it is called just after instantiation (constructor) and times thereafter. Additionally, it is called when making copies (clones) of the object. That is an operation where you really don't want to be selecting/creating objects because there may be no real document (it may be a copied document for render, for instance) or changing the document could lead to crashes. There are plenty of valid message points to consider for doing this as Scott notes.
-
On 06/12/2014 at 08:51, xxxxxxxx wrote:
Thanks for the info guys.
I guess to be safe I'll just create a command plugin/script to do this instead. -
On 07/12/2014 at 13:41, xxxxxxxx wrote:
You may also need to initialize the InExclude before you start setting data in it.
Try the following...
bc->SetData(INEX, GeData(CUSTOMDATATYPE_INEXCLUDE_LIST, DEFAULTVALUE)); //This makes sure its initialized or clears it if there is already content in it. Do this in the Init method. //Do the rest later on, since as described making selections during initialization is not a good idea. InExcludeData *inex = nullptr; inex = (InExcludeData* )bc->GetCustomDataType(INEX, CUSTOMDATATYPE_INEXCLUDE_LIST); if (inex) { for(i = 0; i < k; i++) { inex->InsertObject((BaseList2D* )selection->GetIndex(i), 0); } }
-
On 08/12/2014 at 04:11, xxxxxxxx wrote:
Do it in the MSG_MENUPREPARE message.
-
On 08/12/2014 at 08:56, xxxxxxxx wrote:
Originally posted by xxxxxxxx
You may also need to initialize the InExclude before you start setting data in it.
Try the following...
bc->SetData(INEX, GeData(CUSTOMDATATYPE_INEXCLUDE_LIST, DEFAULTVALUE)); //This makes sure its initialized or clears it if there is already content in it. Do this in the Init method. //Do the rest later on, since as described making selections during initialization is not a good idea. InExcludeData *inex = nullptr; inex = (InExcludeData* )bc->GetCustomDataType(INEX, CUSTOMDATATYPE_INEXCLUDE_LIST); if (inex) { for(i = 0; i < k; i++) { inex->InsertObject((BaseList2D* )selection->GetIndex(i), 0); } }
Originally posted by xxxxxxxx
Do it in the MSG_MENUPREPARE message.
Just tried doing that and it seems to work now. I'll keep on testing to make sure I didn't mess anything else up.
This is what I placed inside Init:
bc->SetData(INEX, GeData(CUSTOMDATATYPE_INEXCLUDE_LIST, DEFAULTVALUE));
And this is in Message:
if(type == MSG_MENUPREPARE){ BaseDocument *doc = ((BaseDocument* )t_data); if(!doc){ GePrint("nodoc");//not sure if this section is needed, keeping it for now. return TRUE; } BaseContainer *bc = ((BaseObject* )node)->GetDataInstance(); AutoAlloc<AtomArray> selection; if(!selection){ return TRUE; } doc->GetActiveObjects(*selection, GETACTIVEOBJECTFLAGS_SELECTIONORDER); if(selection->GetCount()){ Int64 i, k; k = selection->GetCount(); GePrint("selected: "+String().IntToString(k)); InExcludeData *inex; inex = (InExcludeData* )bc->GetCustomDataType(INEX, CUSTOMDATATYPE_INEXCLUDE_LIST); for(i = 0; i < k; i++){ inex->InsertObject((BaseList2D* )selection->GetIndex(i), 0); } } }
Thanks guys!