On 11/10/2016 at 02:54, xxxxxxxx wrote:
this is actually not the way Cinema 4D works and it's pretty uncommon. I'm not aware of any features in Cinema behaving this way. For example using the Active Object Dialog (from the cinema4dsdk examples) you can easily verify, that after deleting a Physical Sky, there's still a hidden Sky Material left over.
So, unfortunately, no, there are no direct means to achieve what you want.
That being said, I had a weird idea, that might work for you or not. Neither tested, nor an official MAXON recommendation. And always make sure, you are in the main thread, when changing the scene (i.e. deleting materials).
But you might want to play around with it nevertheless to see if it works for you:
- Create a SceneHook plugin which holds references to the objects and materials belonging to these. Your object generator would then register objects and materials in this SceneHook on creation.
- Now, have the SceneHook react either on certain change messages or on an event fired in Free() of your generated object.
- In SceneHook reacting on above event, you check the BaseLinks to your generated objects. If a link is broken, it (obviously) means the object got either deleted or got made editable.
- Then you can check the material(s) belonging to the removed object, if these are still assigned to anything. Probably easier than a message is to use the MatAssignData, like so:
mat->GetParameter(ID_MATERIALASSIGNMENTS, d, DESCFLAGS_GET_0);
MatAssignData* const mad = (MatAssignData* )d.GetCustomDataType(CUSTOMDATATYPE_MATASSIGN);
if (mad == nullptr)
// then use e.g. mat->GetObjectCount()
- Throw away those unused materials.
This of course has one obvious major drawback. The deletion of materials is not atomic with the deletion of the generated object, so you would have an inevitable additional undo step for the user.
And you'd need to add further measures to keep the data in the SceneHook up to date. E.g. when a scene gets loaded or the BaseDocument gets copied.
But I guess, you are already aware of such issues, as you run into these in other occasions as well. For example, when your generator object is being copied and pasted into another document.
As mentioned before, please do not take this as a MAXON proven recipe, but rather as a basis for brainstorming and tests.
Another way simpler option might be a "cleanup materials" CommandData plugin accompanying your ObjectData plugin. It could work two ways. Again you could have a SceneHook to store references to "your" materials. Or you could mark materials by storing something at your plugin ID in the BaseContainer of a material. In this way, yes, the user would need to click a button to manually clean up redundant materials, but on the other hand you wouldn't introduce a completely new behavior which is harder to implement and harder to test (in all situations and consequences).