How To Get At Shader Options?

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 05/05/2011 at 12:01, xxxxxxxx wrote:

User Information:
Cinema 4D Version:   12 
Platform:   Windows  ;   
Language(s) :     C++  ;

---------
Sorry. Noob question again.

I know how to add a shader to one of the channels:

  BaseMaterial *mat = doc->GetFirstMaterial(); // Get the first material and assign a variable to it   
  if(!mat) return TRUE; // Error handling  
    
  BaseContainer *data = mat->GetDataInstance(); // Get the material's container    
  BaseShader *shd = BaseShader::Alloc(Xsimplenoise); // Creates simple noise instance....For other types(fresnel,etc..). Look up  "enum Xbase"  in the SDK    
  if(!shd) return FALSE;  
    
  data->SetLink(MATERIAL_COLOR_SHADER, shd); // Adds simple noise to the color channel in memory only    
  mat->InsertShader(shd, NULL); // Adds simple noise to the channel from memory    
    
  mat->Message(MSG_UPDATE); // update the changes  
  mat->Update(TRUE, TRUE); // updates the material icon  

But once I add a shader(fresnel, gradient, simplenoise, ect.) to the channel. How do I drill into that shader so I can change the parameters in them?

-ScottA

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 06/05/2011 at 06:18, xxxxxxxx wrote:

As with every class derived from BaseList2D you can simply access it's container, either through GetDataInstance() or C4DAtom::Get/SetParameter(). Basically the same as you would change object or tag parameters.

cheers,
Matthias

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 06/05/2011 at 07:48, xxxxxxxx wrote:

Thanks for the reply.

I've been trying to use the Get/SetParameter() method. like this:
shd->SetParameter(DescID(NOISESHADER_SCALEX), GeData(2.0), DESCFLAGS_SET_0);

I wasn't even sure if using this was the right method to get at the data. So thanks for confirming that for me.
But NOISESHADER_SCALEX produces an undefined error.
I must be missing something really simple.

-ScottA

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 06/05/2011 at 10:10, xxxxxxxx wrote:

You will probably need to include the header from the resource/modules/shader/res/description folder.

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 06/05/2011 at 10:25, xxxxxxxx wrote:

Once again..You saved my butt Robert. 👍

I got the ID: NOISESHADER_SCALEX by dragging from the dialog into the console.
But I could not find any reference to this ID anywhere in my file structure.
I have been using the built-in Windows Vista search option. And it usually finds things like this for me very well. But in this case it failed me.

Do you have a favorite program, or method, you use search through all of the files for specific ID's?
It looks like I can't trust the Windows search anymore.

-ScottA

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 06/05/2011 at 10:44, xxxxxxxx wrote:

Windows 7 search seems to do the trick every time.  😄  "Hint Hint"  HAHA

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 06/05/2011 at 10:47, xxxxxxxx wrote:

Even the Windows 7 search can be trick-y. 🙂

I use something called Agent Ransack.  It works brilliantly!

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 06/05/2011 at 11:10, xxxxxxxx wrote:

I'll check it out.
But..I'm stuck again. (Don't kill me. I'm trying hard ).

Now I need to know how to change the gradient knots.
All I can find is examples on creating brand new gradients from scratch using the gradient class.
But what I need to know is just how to change the .pos values and the Vector() values of the two existing knots.

I'll post the complete code when I'm done. So anyone else new to this stuff doesn't have to ask you guys these same simple questions over again.

-ScottA

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 06/05/2011 at 13:43, xxxxxxxx wrote:

I couldn't figure out how to edit existing gradients. So I tried allocating a new one. And it seems to replace the old one. So I guess that will work. *shrug*

Here's the entire plugin code:

#include "c4d.h"  
#include "c4d_symbols.h"  
#include "../../cinema4dsdk/res/description/xsdkgradient.h"  
#include "../../modules/shader/res/description/xnoise.h"  
  
#define PLUGIN_ID    10000010 // ID FOR TESTING ONLY!!!!!!!!!!  
  
class SimplePlugin : public CommandData  
{      
  public:  
      SimplePlugin(); //The Constructor                  
      virtual Bool      Execute(BaseDocument *doc);  
};  
  
SimplePlugin::SimplePlugin() // The Constructor  
{  
  //not used in this example  
}  
  
Bool SimplePlugin::Execute(BaseDocument *doc)  
{   
  
  BaseMaterial *mat = doc->GetFirstMaterial(); // Get the first material and assign a variable to it   
  if(!mat) return TRUE; // Error handling  
    
  BaseContainer *data = mat->GetDataInstance(); // Get the material's container  
  BaseShader *shd = BaseShader::Alloc(Xsimplenoise); // Creates simple noise instance....For other types(fresnel,etc..). Look up  "enum Xbase"  in the SDK    
  if(!shd) return FALSE; // Error handling  
  
  data->SetLink(MATERIAL_COLOR_SHADER, shd); // Adds a SimpleNoise shader to the color channel in memory only  
  
  BaseContainer *shddata = shd->GetDataInstance(); // Get the shader's container  
  AutoAlloc<Gradient> gradient; // Creates a new gradient  
  if (!gradient) return FALSE; // Error handling  
  
  GradientKnot k1,k2;           // Create two variables to hold the two knot values  
  k1.col = Vector(0.0,0.0,0.0); // First knot's color is black  
  k1.pos = 0.0;                 // First knot's position   
  
  k2.col = Vector(1.0,1.0,1.0); // Second knot's color is white  
  k2.pos = 1.0;                 // Second knot's position   
  
  gradient->InsertKnot(k1);  //Adds the First knot from memory  
  gradient->InsertKnot(k2);  //Adds the Second knot from memory  
  
  shddata->SetData(SDKGRADIENTSHADER_COLOR,GeData(CUSTOMDATATYPE_GRADIENT,gradient)); // Executes the knot changes from memory      
  shddata->SetData(SDKGRADIENTSHADER_MODE,GeData(1)); //Sets the mode<---BROKEN!!   
    
  shd->SetParameter(DescID(NOISESHADER_SCALEX), GeData(5.0), DESCFLAGS_SET_0); // Sets the scaleX value  
  shd->SetParameter(DescID(NOISESHADER_SCALEY), GeData(5.0), DESCFLAGS_SET_0); // Sets the scaleY value  
  mat->InsertShader(shd, NULL); // Adds the Simple Noise to the color channel from memory with all it's settings made   
    
  mat->Message(MSG_UPDATE); // update the changes  
  mat->Update(TRUE, TRUE); // updates the material icon  
  void Free(BaseMaterial*& mat); // Free memory used in the code(not sure if this is needed)  
  
  return true;  
}  
  
Bool RegisterSimplePlugin()  
{    
  return RegisterCommandPlugin(PLUGIN_ID, GeLoadString(IDS_My_Simple_Plugin), 0, AutoBitmap("icon.tif"), String("Help text Goes here"), gNew SimplePlugin);                                                                        
}

I hope this helps any newbs out there get up running a lot easier.
The mode option is still broken. But I'm exhausted from starring at this thing. So I'm taking a break.

Thanks for the help guys,
-ScottA

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 09/05/2011 at 02:48, xxxxxxxx wrote:

There is no need to allocate a Gradient if you just want to change it in an existing shader.

Here is a simple example. It sets the knot's postion to a random value.

  
GeData d;  
  
// get the data  
if (shd->GetParameter(DescLevel(SLA_GRADIENT_GRADIENT), d, DESCFLAGS_GET_0))  
{  
  //get the Gradient custom data  
  Gradient *gd = (Gradient* )d.GetCustomDataType(CUSTOMDATATYPE_GRADIENT);  
  
  if (gd)  
  {  
      // iterate through all knots and set them randomly  
      LONG kcnt = gd->GetKnotCount();  
  
      Random rnd;  
      rnd.Init(436357);  
  
      for (LONG i=0; i<kcnt; i++)  
      {  
          GradientKnot knot = gd->GetKnot(i);  
          knot.pos = rnd.Get01();  
          gd->SetKnot(i, knot);  
      }  
        
      // set the gradient  
      shd->SetParameter(DescLevel(SLA_GRADIENT_GRADIENT), d, DESCFLAGS_SET_0);  
  
      shd->Message(MSG_UPDATE);  
  
      EventAdd();  
  }  
}  

Also check the GradientShader.cpp SDK example for some more sample code.

cheers,
Matthias

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 09/05/2011 at 07:34, xxxxxxxx wrote:

Thank you. 👍

-ScottA

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 09/05/2011 at 10:27, xxxxxxxx wrote:

Still doesn't work for me. 😠
It looks like the problem begins when trying to get the gradient's container:

Bool SimplePlugin::Execute(BaseDocument *doc)  
{   
  
  BaseMaterial *mat = doc->GetFirstMaterial(); // Get the first material and assign a variable to it   
  if(!mat) return TRUE; // Error handling  
  
  BaseContainer *data = mat->GetDataInstance(); // Get the material's container  
  BaseShader *shd = BaseShader::Alloc(Xsimplenoise);  
  data->SetLink(MATERIAL_COLOR_SHADER, shd); // Adds a SimpleNoise shader to the color channel in memory only  
  mat->InsertShader(shd, NULL); // Adds the Simple Noise to the color channel from memory  
  mat->Message(MSG_UPDATE); // update the changes  
  mat->Update(TRUE, TRUE); // updates the material icon  
  EventAdd();  
  //////////////////     EVERYTHING IS WORKING AT THIS POINT   /////////////////////////////////////  
  
 //Now lets try to access the gradient and it's parameters   
  
GeData d;  
if (shd->GetParameter(DescLevel(SLA_GRADIENT_GRADIENT), d, DESCFLAGS_GET_0))  
 {  
  GePrint("Is this working so far?"); //<-----Yes. This does print and proves that everything is working at this point  
  
  Gradient *gd = (Gradient* )d.GetCustomDataType(CUSTOMDATATYPE_GRADIENT); //get the gradient's custom data  
  
  if (gd) GePrint("true");  
  else GePrint ("false"); // <-------Prints false. The code is broken. Starting from Gradient *gd  
                          // We are not properly accessing the gradients container. We cannot continue until this is fixed  
 }

I'm sure I'm missing something really simple.

-ScottA

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 17/05/2011 at 01:45, xxxxxxxx wrote:

SLA_GRADIENT_GRADIENT is the wrong ID for the gradient of the Simple Noise shader. Please use NOISESHADER_COLOR instead.

cheers,
Matthias

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 17/05/2011 at 11:42, xxxxxxxx wrote:

Thanks for sticking with me on this. I'm almost there now. But I have one final problem.
I can't get the gradient's mode to change:

Here are my list of includes:

#include "c4d.h"  
#include "c4d_symbols.h"  
#include "../../cinema4dsdk/res/description/xsdkgradient.h"  
#include "../../modules/shader/res/description/xnoise.h"  
#include "../../modules/xtensions/res/description/dgradient.h"

And here's my code:

Bool SimplePlugin::Execute(BaseDocument *doc)  
{   
  
  BaseMaterial *mat = doc->GetFirstMaterial(); // Get the first material and assign a variable to it   
  if(!mat) return TRUE; // Error handling  
    
  BaseContainer *data = mat->GetDataInstance(); // Get the material's container  
  BaseShader *shd = BaseShader::Alloc(Xsimplenoise); // Creates simple noise instance....For other types(fresnel,etc..). Look up  "enum Xbase"  in the SDK    
  if(!shd) return FALSE; // Error handling  
  
  data->SetLink(MATERIAL_COLOR_SHADER, shd); // Adds a SimpleNoise shader to the color channel in memory only  
  
  BaseContainer *shddata = shd->GetDataInstance(); // Get the shader's container  
    
GeData d;  
if (shd->GetParameter(DescLevel(NOISESHADER_COLOR), d, DESCFLAGS_GET_0)) // If it's a Simple Noise shader. Get it's attributes  
 {  
  Gradient *gd = (Gradient* )d.GetCustomDataType(CUSTOMDATATYPE_GRADIENT); //Get the gradient's custom data and assign it to a variable  
        
   if (gd)  
    {          
      LONG kcnt = gd->GetKnotCount(); // Get the total number of knots in case we need it later  
      GradientKnot first = gd->GetKnot(0); //Gets the first knot  
      GradientKnot second = gd->GetKnot(1); //Gets the second knot  
  
      first.pos = 0.1;                   // Changes the first knot's position in memory only          
      second.pos = 0.8;                 // Changes the second knot's position in memory only  
      first.col = Vector(0.5, 0.1, 0.0);     // Changes the first knot's color in memory only      
      second.col = Vector(1.0 , 1.0, 1.0); // Changes the second knot's color in memory only      
  
      gd->SetKnot(0, first);         // Execute the first knot's changes from memory  
      gd->SetKnot(1, second);        // Execute the second knot's changes from memory  
        
      // Set the gradient changes  
      shd->SetParameter(DescLevel(NOISESHADER_COLOR), d, DESCFLAGS_SET_0);  
      shd->Message(MSG_UPDATE);  
      EventAdd();  
    }    
  shd->Message(MSG_UPDATE); // Tell C4D that we made some changes  
  EventAdd(); // Update the scene changes  
 }   
  
  shddata->SetData(GRADIENTSUBCHANNEL_INTERPOLATION,GeData(GRADIENTSUBCHANNEL_INTERPOLATION_SMOOTHKNOT)); //<-----------Does Not Work! Mode does not Change!  
  shd->SetParameter(DescID(NOISESHADER_SCALEX), GeData(5.0), DESCFLAGS_SET_0); // Sets the scaleX value  
  shd->SetParameter(DescID(NOISESHADER_SCALEY), GeData(5.0), DESCFLAGS_SET_0); // Sets the scaleY value  
  mat->InsertShader(shd, NULL); // Adds the Simple Noise to the color channel from memory with all it's settings made   
    
  mat->Message(MSG_UPDATE); // update the changes  
  mat->Update(TRUE, TRUE); // updates the material icon  
  void Free(BaseMaterial*& mat); // Free memory used in the code(not sure if this is needed)  
  
  return true;  
}

Any idea what I'm doing wrong with the mode code?

-ScottA