How to set the "Texture preview size" value on a new material?
-
Hey y'all,
Apologies if this is a pretty basic question, but I can't for the life of me figure out how to set the "Texture preview size" value of a new material, as such:
#include <customgui_matpreview.h> Material* const material = Material::Alloc(); if (material == nullptr) return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION); // To-do: Set the CUSTOMDATATYPE_MATPREVIEW to "None" (which is ID = 1) material->Update(TRUE, TRUE);
I've tried every iteration of
GetData()
/SetData()
andGetCustomDataType()
/SetCustomDataType()
I could think of, and yet, I either get an error, or (if no error) the value of the "Texture Preview Size" value is not changed upon being applied onto my object.I was able to set Channel-related values, which is great, so I'm left wondering why I'm struggling with the Material's "Viewport" options.
I've scoured the forum before asking, but to no avail.
Thank you very much in advance! I very much appreciate it.
-
Hey @sasha_janvier,
Thank you for reaching out to us. There seem to be two issues which hold you up here, ID discovery and setting parameters.
ID Discovery
The classic API of Cinema 4D revolves very much around the so called
DescID
, i.e., identifiers which address parameters in scene elements. An important aspect of both Python and C++ development for Cinema 4D is the ability to discover such IDs reliably. There are three ways to do this:- Resource Indices: They exist in our Python and C++ docs, I would however recommend using the Python docs for this, as the overview is there a bit more useable due to the better search of our Python docs. The idea is to search for a resource symbol (
Mmaterial
in your case) or the English label or ID of a parameter, e.g.,'Viewport Display'
(the latter only works in the Python docs and is there far from perfect too). For your case, this would you lead here (Python) or here (C++). In the C++ docs, you could also search directly for mmaterial.h but this will not give you the fully parsed resource but just the header file. This will tell you then everything you need to know about a parameter like its ID, label, and the values it can take (when it is a cycle):
- Console: The Python console of Cinema 4D can be used to discover parameter identifiers via drag and drop. This is probably the most common way to do this, you can however only discover parameter identifier symbols in this manner, not the symbols for values (e.g., for
node[ID_SOME_PARAM] = ID_SOME_CONST
, onlyID_SOME_PARAM
can be discovered, not the symbol for the valueID_SOME_CONST
).
- Grepping: I personally still like simply grepping the resource folder of Cinema 4D. It is a bit more raw approach, but there we have more control of how to search for information (we could also for example search by the French, German, Chinese etc. label or simply lean into the full power of regular expressions). You can use the OG
grep
for this, a dedicated app like Agent Ransack, or just the search of VS, VS Code, or XCode which are also quite powerful these days.
So, the parameter symbol would be
MATERIAL_PREVIEWSIZE
and the symbol for the value would beMATERIAL_PREVIEWSIZE_DEF
(there is no 'None', only 'Default' and 'No Scale', I assumed you meant the former).Setting Parameters
What also shines a bit through in your question, is that you seem to be unaware of the various ways how you can set the parameters of a node. Your comment implies that you tried to do this the
BaseContainer
route, i.e., callBaseContainer* const data = myNode->GetDataInstance()
, and then operate on this container. And while this works, this is not the only way to set parameters. The more atomic approach is C4DAtom::SetParameter. Setting your preview size could look something like this:if (!material->SetParameter(ConstDescID(DescLevel(MATERIAL_PREVIEWSIZE), MATERIAL_PREVIEWSIZE_DEF, DESCFLAGS_SET::NONE)) return maxon::IllegalArgumentError(MAXON_SOURCE_LOCATION, "Failed to set preview size."_s);
The advantage of
Get/SetParameter
over the data container is that it reflects all parameters of a node (you will not find any of the base description parameters of a node in its data container, like for example its name) and that you can make use ofDESCFLAGS_SET
andDESCFLAGS_GET
to, for example, emulate a user interaction when setting a parameter. If you want to know more, start reading here.Cheers,
Ferdinand - Resource Indices: They exist in our Python and C++ docs, I would however recommend using the Python docs for this, as the overview is there a bit more useable due to the better search of our Python docs. The idea is to search for a resource symbol (
-
Once again, I am immensely grateful for your generous and incredibly helpful assistance, @ferdinand !
I don’t know why I didn’t mention
SetParameter()
in my original message, as this was the first thing I attempted before experimenting with the other methods I mentioned.Thank you once again. I was able to throughly familiarize myself with
GetParameter()
andSetParameter()
today.