[Closed] Prevent modifier collapse?
Hi,
I’m writing an object modifier plugin in C++ that allows to set appleseed-specific attributes on objects of the scene, in the spirit of the Arnold Properties Modifier:
https://support.solidangle.com/display/A5AF3DSUG/Arnold+Properties+Modifier
Similarly to that Arnold modifier, I’d like my modifier to be non-collapsable (because there is nowhere else to store the attributes).
What is the preferred way to achieve this?
Franz
How would collapsing the stack be any different from deleting the modifier ?
I’m not sure to understand what you mean. My point is that I can see how collapsing a whole stack while retaining the appleseed object properties modifier would be useful and convenient, if that’s something the SDK allows to implement.
You could use the modifier as the editor for appdata attached to the base object, so when the stack is collapsed the data is still available to the renderer. Then if the user needs to edit the data they can add another modifier.
That sounds interesting. Where in the base object would the app-specific attributes bet stored?
To be honest, it’s partly to answer this question that I decided to create a modifier. The idea is that the modifier has the double duty of storing the attributes and offering a way to edit them. One benefit I can see (and it’s also mentioned in the Arnold docs) is that the modifier can be copied and used on other objects.
how is about Custom Attribute? == can store everything, can be editted using UI, not collapsable…
just curious… when you add Arnold modifier to a Box object for example, and ask “classof” this objects with the modifier what does the system say?
If you add a Attribute Holder the object changes to Editable_mesh
thinking about it, I would probably go for hanging the appdata off the dependent nodes as it’s what your renderer will reference the most anyway. These can be accessed from the modifier using a DependentEnumProc object and the ReferenceTarget :: DoEnumDependents function. There are several examples of this in the sdk samples to go by also a few examples of using AppData chunks.
The trickiest part of doing it like this is, when say 2 nodes have had different settings applied and a new modifier is applied to both how do you display the differing data sets. 3 way checkbox are ok for booleans and pull downs can be forced to show an “empty value”. Sometimes items have to be disabled altogether.
I can see at least three alternatives:
-
Stick to custom attributes on objects. Just instruct users to add attributes with the proper name, type and value in order to enable appleseed-specific features. Pros: little work. Cons: not user friendly; attributes are not immediately visible to the user; attributes cannot be easily copied from one object to another.
-
Use custom attributes on objects for storage, but implement a custom modifier for attributes edition. Pros: user friendly; easy to copy attributes to other objects; survives collapsing. Cons: more work; attributes will likely remain after the modifier is removed.
-
Implement a custom modifier for attributes edition AND storage. Pros: user friendly; clear behavior (removing the modifier removes the attributes); easy to copy attributes to other objects. Cons: more work; collapsing the modifiers stack kills the attributes.
I’m really in favor of option 3, IF it is possible to make the custom modifier survive a collapse. I’m not sure how the Arnold Properties Modifier does it, or even if it behaves the way I think it does (I’m on 3ds Max 2017 right now, so no Arnold).
you have to use NotifyPostCollapse method to set the modifier back.
something like:
void YOURModifier::NotifyPostCollapse(INode *node,Object *obj, IDerivedObject *derObj, int index)
{
Object *bo = node->GetObjectRef();
IDerivedObject *derob = NULL;
if(bo->SuperClassID() != GEN_DERIVOB_CLASS_ID)
{
derob = CreateDerivedObject(obj);
node->SetObjectRef(derob);
}
else derob = (IDerivedObject*) bo;
// Add ourselves to the top of the stack
derob->AddModifier(this,NULL,derob->NumModifiers());
// Reinsert our local mod data
// ...
}