Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    How to change the tex path in a existing material

    SDK Help
    0
    11
    1.0k
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • H
      Helper
      last edited by

      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.

      1 Reply Last reply Reply Quote 0
      • H
        Helper
        last edited by

        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

        1 Reply Last reply Reply Quote 0
        • H
          Helper
          last edited by

          On 24/06/2016 at 06:22, xxxxxxxx wrote:

          Hello Motiva,

          was you question answered?

          Best wishes,
          Sebastian

          1 Reply Last reply Reply Quote 0
          • H
            Helper
            last edited by

            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?

            1 Reply Last reply Reply Quote 0
            • H
              Helper
              last edited by

              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

              1 Reply Last reply Reply Quote 0
              • H
                Helper
                last edited by

                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.

                1 Reply Last reply Reply Quote 0
                • H
                  Helper
                  last edited by

                  On 05/09/2016 at 05:10, xxxxxxxx wrote:

                  Hello,

                  could you explain what exactly you mean with "open scene time"?

                  best wishes,
                  Sebastian

                  1 Reply Last reply Reply Quote 0
                  • H
                    Helper
                    last edited by

                    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

                    1 Reply Last reply Reply Quote 0
                    • H
                      Helper
                      last edited by

                      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

                      1 Reply Last reply Reply Quote 0
                      • H
                        Helper
                        last edited by

                        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.

                        1 Reply Last reply Reply Quote 0
                        • First post
                          Last post