MSG_MENUPREPARE not sent to BaseShaders
-
Hi,
I think this is either an API bug, or a mistake in the docs:
https://developers.maxon.net/docs/cpp/2023_2/group___m_s_g.html#ga58e4d06ecc0352d135578cbc4d4e7b5eQuote:
#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 myShaderData
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?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.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 viaTexBoxGui::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.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), and5707
which is not aMSG_
message but the id ofXbase
. So, nothing particularly useful for what you want to do.The bottom line here is:
- I will ask the devs was their take on this is.
- I have added a task for us to update the docs, thanks for the hint! This might also extend further than just shaders, because while I could find the message being set off for objects and materials, I could not find it being set off for tags in our C++ code base. But I might have just overlooked it, will have to try with a
TagData
plugin.
Finally, could you elaborate why you need
MSG_MENUPREPARE
and whyNodeData::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 expectMSG_MENUPREPARE
to be more "unique" (for the lack of a better word), asNodeData::Init
is being called quite often in more recent versions of Cinema 4D?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.
InMSG_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. InNodeData::Init()
,node->GetDocument()
returnsnullptr
, unfortunately. The node isn't yet part of the document, whenInit()
is called.Cheers,
Frank -
Hello @fwilleke80,
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.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.
Cheers,
Ferdinand -
Thanks!
No stress, I basically just needed this to be validated, so I can use a hacky workaround with peace of conscienceCheers,
Frank -
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.