<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Changing description of material nodes dynamically]]></title><description><![CDATA[<p dir="auto">Hi,</p>
<p dir="auto">I have two questions regarding the descriptions of nodes.</p>
<p dir="auto">My first question is, if it is possible and how to change some description property of a node port, based on the value of another <em>constant</em> port. As an example, in a <code>NodeData::GetDDescription(..)</code> one can easily read a parameter and change the description of another parameter (e.g. change the name of one parameter based on a checkbox).<br />
Is something similar possible to do in material nodes (or nodes in general) and how?</p>
<p dir="auto">My second question is related to the first one in regards of dynamic changes of nodes. I tried using a custom GUI implementation based on the <code>example.nodes</code> plugin in the SDK. In particular I used the implementation in <code>example.nodes/source/gui/customgui_string.cpp</code> as a reference for using a custom GUI. I found that the <code>getDataCallback</code> parameter delegate can be used to actually get the GraphNode for a node in <code>UiConversionCustomGuiString::CreateC4DDescription(..)</code>. But my question is if there is a way to trigger this function to be called again upon changes on the node, to allow dynamic updates on the node based on port value in the node?</p>
<p dir="auto">Thanks in advance <img src="http://developers.maxon.net/forum/assets/plugins/nodebb-plugin-emoji/emoji/android/1f642.png?v=0b8ddba251d" class="not-responsive emoji emoji-android emoji--slightly_smiling_face" style="height:23px;width:auto;vertical-align:middle" title=":)" alt="🙂" /></p>
]]></description><link>http://developers.maxon.net/forum//topic/14158/changing-description-of-material-nodes-dynamically</link><generator>RSS for Node</generator><lastBuildDate>Tue, 17 Mar 2026 07:10:01 GMT</lastBuildDate><atom:link href="http://developers.maxon.net/forum//topic/14158.rss" rel="self" type="application/rss+xml"/><pubDate>Wed, 24 Aug 2022 16:31:28 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Changing description of material nodes dynamically on Wed, 31 Aug 2022 08:23:32 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/forum/user/deyan">@<bdi>deyan</bdi></a> said in <a href="https://developers.maxon.net/forum/post/69713" target="_blank" rel="noopener noreferrer nofollow ugc">Changing description of material nodes dynamically</a>:</p>
<blockquote>
<p dir="auto">is there an alternative for earlier SDK versions?</p>
</blockquote>
<p dir="auto">In our example, you have the files nodessystem_observer.h/cpp this shows how to create a ticket system. This system is based on observable that you can use, those observables are accessible in the GraphModelInterface or the NodeSystemManagerInterface.</p>
<ul>
<li>ObservableTransactionStarted</li>
<li>ObservableTransactionCommitted</li>
<li>ObservableTransactionRolledBack</li>
</ul>
<p dir="auto">You have another example in <a href="https://developers.maxon.net/docs/cpp/2023_2/page_maxonapi_graphmodelinterface.html#page_maxonapi_graphmodelinterface_edit" target="_blank" rel="noopener noreferrer nofollow ugc">our manual</a></p>
<p dir="auto">The problem with observable is that you need to be sure that your function is registered or unregistered the right way/time. You need a proper system to handle those "tickets".<br />
For now, you only have this "basic system".</p>
<p dir="auto">Cheers,<br />
Manuel</p>
]]></description><link>http://developers.maxon.net/forum//post/69722</link><guid isPermaLink="true">http://developers.maxon.net/forum//post/69722</guid><dc:creator><![CDATA[Manuel]]></dc:creator><pubDate>Wed, 31 Aug 2022 08:23:32 GMT</pubDate></item><item><title><![CDATA[Reply to Changing description of material nodes dynamically on Tue, 30 Aug 2022 10:11:42 GMT]]></title><description><![CDATA[<p dir="auto">Another small question that came to mind - this registration function <code>RegisterValueChangedMessage(..)</code> seems to have been added in R26 SDK - is there an alternative for earlier SDK versions?</p>
]]></description><link>http://developers.maxon.net/forum//post/69713</link><guid isPermaLink="true">http://developers.maxon.net/forum//post/69713</guid><dc:creator><![CDATA[Deyan]]></dc:creator><pubDate>Tue, 30 Aug 2022 10:11:42 GMT</pubDate></item><item><title><![CDATA[Reply to Changing description of material nodes dynamically on Mon, 29 Aug 2022 17:19:47 GMT]]></title><description><![CDATA[<p dir="auto">I forgot an important point; the message will only be called at edit time (if the user changes the value). If the field is animated, the message will not get triggered.</p>
<p dir="auto">About just triggering the function i need to check if we can do something with timestamp.</p>
]]></description><link>http://developers.maxon.net/forum//post/69704</link><guid isPermaLink="true">http://developers.maxon.net/forum//post/69704</guid><dc:creator><![CDATA[Manuel]]></dc:creator><pubDate>Mon, 29 Aug 2022 17:19:47 GMT</pubDate></item><item><title><![CDATA[Reply to Changing description of material nodes dynamically on Mon, 29 Aug 2022 16:51:54 GMT]]></title><description><![CDATA[<p dir="auto">Hi @m_magalhaes, this is exactly what I was looking for. It works like a charm for my first usecase.</p>
<p dir="auto">But for the second part I encountered just a slight inconvenience. In my second usecase I actually don't want to change parameter name, I just want <code>CreateC4DDescription(..)</code> to be called again. From what I tested, if the name is set with the same value, the description creation is not triggered. I also tried changing another (seemingly irrelevant) attribute of the node, but that did not trigger a description change either (in particular I tried changing <code>maxon::NODE::BASE::COMMENT</code>).<br />
Finally, I tried adding a new <em>hidden</em> port, that is not actually used, just to change its name when the description change function should be called - and this seems to work as expected. I was just wondering if there is a better solution that may achieve the same result without a dummy port?</p>
<p dir="auto">Cheers,<br />
Deyan</p>
]]></description><link>http://developers.maxon.net/forum//post/69703</link><guid isPermaLink="true">http://developers.maxon.net/forum//post/69703</guid><dc:creator><![CDATA[Deyan]]></dc:creator><pubDate>Mon, 29 Aug 2022 16:51:54 GMT</pubDate></item><item><title><![CDATA[Reply to Changing description of material nodes dynamically on Mon, 29 Aug 2022 15:18:13 GMT]]></title><description><![CDATA[<p dir="auto">Hi and sorry for the late reply,</p>
<p dir="auto">you can react to a change in a node parameter registering a changed message with <code>RegisterValueChangedMessage</code><br />
You need to define the Node ID and the port. If you change some parameter this will call an update of the UI and CreateC4DDescription will be called.</p>
<p dir="auto">From there you can achieve what you want. I did not try but as you said, in the customgui_string you can defined parameter for the custom GUI.</p>
<p dir="auto">Let me know if it is not enough.</p>
<pre><code>#include "maxon/datadescriptiondefinitiondatabase.h"
#include "maxon/datadescription_ui.h"
#include "maxon/datadescription_nodes.h"
#include "maxon/graph.h"
#include "customnode-customnodespace_descriptions.h"

static maxon::Result&lt;void&gt; ColorChanged(const maxon::DataDictionary&amp; userData, maxon::DataDictionary&amp; multiSelectionStorage)
{
	iferr_scope;

	maxon::GraphModelRef graph = userData.Get(maxon::ARGUMENTS::NODECORE::GRAPHMODEL) iferr_return;
	// Node that owns the port (NODECORE::PORTPATH).
	maxon::IoNodePath nodePath = userData.Get(maxon::ARGUMENTS::NODECORE::NODEPATH) iferr_return;
	// Internal port on which the callback was registered.
	maxon::NodePath innerPortPath = userData.Get(maxon::ARGUMENTS::NODECORE::INNERPORTPATH) iferr_return;

	// Should always just be valid if the callback is fired.
	CheckAssert(graph);
	CheckAssert(nodePath.first.IsPopulated());
	CheckAssert(innerPortPath.IsPopulated());




	maxon::GraphNode currentNode = graph.GetNode(nodePath.first);
	if (!currentNode.IsValid())
		return maxon::NullptrError(MAXON_SOURCE_LOCATION);

	const maxon::GraphNode colorA = graph.GetNode(innerPortPath);
	if (!colorA.IsValid())
		return maxon::NullptrError(MAXON_SOURCE_LOCATION);
	const maxon::GraphNode hybridPort = currentNode.GetInputs().FindChild(maxonexample::NODE::USERNODE::HYBRID) iferr_return;
	if (!colorA.IsValid())
		return maxon::NullptrError(MAXON_SOURCE_LOCATION);

	const maxon::ColorA colorAValue = colorA.GetDefaultValue(maxon::ColorA(0)) iferr_return;
	if (colorAValue.r &gt; 0.5)
	{
		// Make the graph modifiable.
		maxon::GraphTransaction trans = graph.BeginTransaction() iferr_return;

		hybridPort.SetValue(maxon::NODE::BASE::NAME, "Code Red"_s) iferr_return;

		// Apply the change to the graph.
		return trans.Commit();
	}
	return maxon::OK;
}


MAXON_INITIALIZATION(
	[]() -&gt; maxon::Result&lt;void&gt;
	{
		iferr_scope;
		maxon::DataDescriptionDefinitionDatabaseInterface::RegisterValueChangedMessage(
			maxonexample::NODE::USERNODE::GetId(), maxonexample::NODE::USERNODE::COLORA,
			maxon::DescriptionMessageFunction(maxon::DESCRIPTION::UI::BASE::COMMANDCONTEXT.ENUM_NIMBUSCORE, nullptr, nullptr, ColorChanged)) iferr_return;
		return maxon::OK;
	}, nullptr);

</code></pre>
<p dir="auto">Cheers,<br />
Manuel</p>
]]></description><link>http://developers.maxon.net/forum//post/69701</link><guid isPermaLink="true">http://developers.maxon.net/forum//post/69701</guid><dc:creator><![CDATA[Manuel]]></dc:creator><pubDate>Mon, 29 Aug 2022 15:18:13 GMT</pubDate></item></channel></rss>