Your browser does not seem to support JavaScript. As a result, your viewing experience will be diminished, and you have been placed in read-only mode.
Please download a browser that supports JavaScript, or enable it if it's disabled (i.e. NoScript).
Hi,
I think this is either an API bug, or a mistake in the docs: https://developers.maxon.net/docs/Cinema4DCPPSDK/html/group___m_s_g.html#ga58e4d06ecc0352d135578cbc4d4e7b5e
Quote:
#define MSG_MENUPREPARE Allows tags, objects, shaders etc. to do some setup work when called from the menu. The corresponding data is the current BaseDocument.
I just noticed that MSG_MENUPREPARE is not received in my ShaderData plugin, at least not in R25 (didn't check earlier releases). Is there any other way to have a shader do something when it's created by the user?
MSG_MENUPREPARE
ShaderData
Cheers, Frank
Hello @fwilleke80,
Thank you for reaching out to us. For clarity, you are talking about a shader being created with this menu, right?
I debugged a bit against Cinema 4D to find out more. Other than the more "top-level" menus as they exist for object, material, and tag creation, we are here deep inside the parameters of a node, as this all happens inside the custom GUI TexBoxGui, or more specifically its internal counterpart, which is used to display such base link parameters for shaders.
TexBoxGui
When you click on the little popup arrow button, Cinema builds first the popup menu, evaluates the user input, and then sends the data on a gigantic message journey (which I frankly did not step through in its entirety), and at the end the data then comes out as an already instantiated BaseList2D which is set via TexBoxGui::SetData(). So, there is no obvious point for me where the message should be emitted, aside from the distant corner in the classic API core where the shader, which is then finally set, is actually being instantiated. TexBoxGui, the initiator of the action, does not send any messages you can receive.
BaseList2D
TexBoxGui::SetData()
When we go the other way around, and simply listen for what is being received in a ShaderData::Message when it is created with that menu, we see three message ids (each sent multiple times): MSG_MULTI_RENDERNOTIFICATION = 1001071, MSG_FILTER = 14 (which are all for the render notifactions), and 5707 which is not a MSG_ message but the id of Xbase. So, nothing particularly useful for what you want to do.
ShaderData::Message
MSG_MULTI_RENDERNOTIFICATION = 1001071
MSG_FILTER = 14
5707
MSG_
Xbase
The bottom line here is:
TagData
Finally, could you elaborate why you need MSG_MENUPREPARE and why NodeData::Init won't be sufficient? You have in both cases access to the document the node is contained in, and you are relatively early in the life cycle of a node. I assume it is because you expect MSG_MENUPREPARE to be more "unique" (for the lack of a better word), as NodeData::Init is being called quite often in more recent versions of Cinema 4D?
NodeData::Init
Cheers, Ferdinand
Hi @ferdinand, thanks for your reply!
For clarity, you are talking about a shader being created with this menu, right?
Exactly.
Finally, could you elaborate why you need MSG_MENUPREPARE and why NodeData::Init won't be sufficient?
The whole point of MSG_MENUPREPARE is to have access to the document the new node is being added to. I wanted to link something from the document in a LINK element in the shader's description. In MSG_MENUPREPARE, I get a pointer to the parent document as message data, so it's no problem to find a scene element and link it in the shader. In NodeData::Init(), node->GetDocument() returns nullptr, unfortunately. The node isn't yet part of the document, when Init() is called.
NodeData::Init()
node->GetDocument()
nullptr
Init()
In NodeData::Init(), node->GetDocument() returns nullptr, unfortunately. The node isn't yet part of the document, when Init() is called.
Eh, right. Well, the only way I see left is the clunky way. You could listen for MSG_MULTI_RENDERNOTIFICATION, as a shader must be rendered when it is instantiated from a menu. Then you need some flag which indicates if something from the document has been evaluated or not for the given node. When a render notification is raised, you check for that flag in the node and carry out something the first time the shader is being rendered. Pretty ugly design, I agree, but the only way I currently see.
MSG_MULTI_RENDERNOTIFICATION
We will see what the developers say, but this can take time, especially since we are currently in a high-workload phase with a closing in release.
Thanks! No stress, I basically just needed this to be validated, so I can use a hacky workaround with peace of conscience
I've changed this back to "Normal topic". It was a question, and it was answered, but since there's no solution, I didn't want to mark it as "solved.