How to change the tex path in a existing material
-
On 09/06/2016 at 09:00, xxxxxxxx wrote:
User Information:
Cinema 4D Version: R17
Platform:
Language(s) : C++ ;---------
I figured it should be easy but unfortunatly it didn'tI have created some materials and they are ok, also I can retrive them by name so thats ok too.
_ BaseMaterial *searchmat = doc->SearchMaterial(name.c_str());_
_ if (!searchmat)_
_ return NULL;_
_
_
My first try was
_ _ BaseShader* bitmapShader = NULL;
_ searchmat->GetParameter(DescLevel(MATERIAL_COLOR_SHADER), bitmapShader , DESCFLAGS_GET_0);_But obviously it didn't work, I tried others like
_ _ GeData data;
_ searchmat->GetParameter(DescLevel(MATERIAL_COLOR_SHADER), data, DESCFLAGS_GET_0);_
_ BaseShader* bitmapShader = (BaseShader* )&data;_But no luck neither
My intention is to find the current loaded texture and if it meets a condition (same file but other path) change it.Thank you in advance.
-
On 09/06/2016 at 13:30, xxxxxxxx wrote:
You can't simply cast the GeData. You have to use this:
BaseShader* bitmapShader = static_cast<BastShader*>(data.GetLink(doc));
where doc is a BaseDocument* to the document that contains the BaseMaterial.
-
On 13/06/2016 at 02:22, xxxxxxxx wrote:
Hello,
using GetParameter() one can access the value stored for a given parameter ID. This value is given in form of a GeData object. This GeData object can store any kind of data. To get the specific data one has to access it using a specific function.
A ShaderLink parameter does not "own" or "store" a shader but it links to an existing shader. So you have to access the BaseLink that represents that link from the GeData object. Using that BaseLink you can then access the linked BaseShader.
Best wishes,
Sebastian -
On 24/06/2016 at 06:22, xxxxxxxx wrote:
Hello Motiva,
was you question answered?
Best wishes,
Sebastian -
On 02/09/2016 at 10:40, xxxxxxxx wrote:
After a long time I come back since I never managed this properly I found an example here https://developers.maxon.net/docs/cpp/2023_2/page_manual_texturetag.html but it didn't work for me as expected
_GeData data;_
_ searchmat->GetParameter(DescID(MATERIAL_COLOR_SHADER), data, DESCFLAGS_GET_0); BaseShader* bitmapShader = static_cast<BaseShader*>(data.GetBaseLink()->GetLink(doc, Xbitmap));_
I never managed to get bitmapShader.
Any idea?
-
On 02/09/2016 at 15:12, xxxxxxxx wrote:
There are two ways to change the image in a material's Xbitmap type shader
-Using the BaseContanier
-Using the Get() & Set() parameter functions
Both work equally well. But Maxon prefers us to use the later whenever possible.BaseContainer method
//The target material BaseMaterial *mat = doc->GetActiveMaterial(); if (!mat) return FALSE; //The file path to the new image //Change this as desired Filename file = Filename("C:\\Users\\user\\Desktop\\myimage.jpg"); //Target the color channel and get it's BaseContainer BaseChannel *ch = mat->GetChannel(CHANNEL_COLOR); BaseContainer bc = ch->GetData(); //Change the container to point to the new image file path bc.SetString(BASECHANNEL_TEXTURE, file.GetString()); //Update the container so it uses the changes ch->SetData(bc); mat->Update(TRUE, TRUE); //Updates the thumbnail image mat->Message(MSG_UPDATE); //Updates the material EventAdd();
Get() & Set() parameter method
//The target material BaseMaterial *mat = doc->GetActiveMaterial(); if (!mat) return FALSE; //The file path to the new image //Change this as desired Filename file = Filename("C:\\Users\\user\\Desktop\\myimage.jpg"); //First test if there is already an Xbitmap shader holding an image in the color channel //Bail out if it doesn't exit GeData data; mat->GetParameter(DescID(MATERIAL_COLOR_SHADER), data, DESCFLAGS_GET_0); BaseShader *shader = static_cast<BaseShader*>(data.GetLink(doc, Xbitmap)); if (!shader || !shader->IsInstanceOf(Xbitmap)) return false; //Get the image that is currently in the shader and print it to the console //This code can be skipped if desired shader->GetParameter(DescID(BITMAPSHADER_FILENAME), data, DESCFLAGS_GET_0); GePrint(data.GetFilename().GetString()); //Change the file path by setting it in the data variable (similar to changing a BaseContainer value) data.SetFilename(file); //Target the file option in the shader and appy the data variable. Which now holds the new file path //The ID for the file option is: BITMAPSHADER_FILENAME shader->SetParameter(DescLevel(BITMAPSHADER_FILENAME), data, DESCFLAGS_SET_0); mat->Update(TRUE, TRUE); //Updates the thumbnail image mat->Message(MSG_UPDATE); //Updates the material EventAdd();
-ScottA
-
On 05/09/2016 at 02:55, xxxxxxxx wrote:
It could be related to the time it happens I followed your second method without luck neither.
I'm testing it at open scene time and it always fails on
if (!shader || !shader->IsInstanceOf(Xbitmap)) return false;
but I'm sure there is one probably the material has not loaded properly yet.
-
On 05/09/2016 at 05:10, xxxxxxxx wrote:
Hello,
could you explain what exactly you mean with "open scene time"?
best wishes,
Sebastian -
On 05/09/2016 at 08:19, xxxxxxxx wrote:
I mean in during opening the document
Message(GeListNode* node, Int32 type, void* data)type==MSG_MULTI_DOCUMENTIMPORTED
-
On 06/09/2016 at 00:33, xxxxxxxx wrote:
Hello,
I have no problem to access the shader when the host material is loaded (implemented in the "Message" function of the material plugin) :
case (MSG_MULTI_DOCUMENTIMPORTED) : { // access shader link GeData data; if (node->GetParameter(2001, data, DESCFLAGS_GET_0)) { BaseDocument* doc = node->GetDocument(); BaseLink* link = data.GetBaseLink(); if (link && doc) { // access shader BaseList2D* shader = link->GetLink(doc); if (shader && shader->IsInstanceOf(Xbitmap)) { // get filename shader->GetParameter(BITMAPSHADER_FILENAME, data, DESCFLAGS_GET_0); GePrint("Used Bitmap: " + data.GetFilename().GetString()); } } } break; }
best wishes,
Sebastian -
On 06/09/2016 at 01:26, xxxxxxxx wrote:
Sorry my object is not a material but a dummy object I'm getting the material by name, but I can retrieve it properly, maybe just in the c4d order the materials are created but no filled.