Gradient evaluation outside of render

  • On 08/05/2015 at 11:31, xxxxxxxx wrote:

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

    It seems the gradient calculate function requires InitRender to be called first.

    Is there a way to evaluate CalcGradientPixel without a render structure or is there a way to initialize the render structure without volume data?


  • On 08/05/2015 at 11:43, xxxxxxxx wrote:

    Here is what I tried:

    colorGradient = (Gradient* )data->GetCustomDataType( GRADIENTID, CUSTOMDATATYPE_GRADIENT );
    InitRenderStruct renderStruct;
    renderStruct.Init( bn->GetDocument() );
    VolumeData *volumeData = VolumeData::Alloc();
    renderStruct.vd = volumeData;
    colorGradient->InitRender( renderStruct );

    I am confused why this not working.

    then try to calculate.


  • On 09/05/2015 at 02:53, xxxxxxxx wrote:

    You don't need no VolumeData for the GradientData. Maybe that is the problem, it works for me with an
    empty InitRenderStruct.

  • On 09/05/2015 at 04:22, xxxxxxxx wrote:

    are you initializing that render struct?


  • On 09/05/2015 at 05:52, xxxxxxxx wrote:

    Nope. Here's how it works in Python:

    import c4d
    def main() :
        gradient = op[c4d.ID_USERDATA,1]
        irs = c4d.modules.render.InitRenderStruct()
        res = gradient.InitRender(irs)
        if res != c4d.INITRENDERRESULT_OK:
            print "InitRender() failed"
            for i in xrange(10) :
                x = i / 9.0
                print gradient.CalcGradientPixel(x)

    And I remember successfully doing it in C++ without calling InitRenderStruct::Init().

  • On 10/05/2015 at 07:25, xxxxxxxx wrote:

    I am trying to get this working within an xpresso node.  If I access the gradient directly from the res file it all works fine.  If I access it through a port, it initializes, has the correct render knot count, but crashes on Calc or FreeRender.


  • On 11/05/2015 at 10:05, xxxxxxxx wrote:


    can you tell us what exactly you mean with "working within an xpresso node"? Are you creating your own GvOperatorData plugin?

    Best wishes,

  • On 11/05/2015 at 10:27, xxxxxxxx wrote:

    I have created a GvOperatorData plugin.  The problem is that I can not use a port for the gradient successfully.  If I use the res static gradient is all fine.  If I use the port gradient, it will init but crashes when calc or free is called.


  • On 12/05/2015 at 10:00, xxxxxxxx wrote:


    in an Xpresso node, you don't handle parameters but ports. These ports must be handled in special ways:

    static Int32 input_ids[] = { GV_TEST_A, GV_TEST_B, 0 };  
    GvValuesInfo ports; // data structure for all ports  
    // init the input ports  
    virtual Bool InitCalculation(GvNode *bn, GvCalc *calc, GvRun *run)  
      return GvBuildValuesTable(bn, ports, calc, run, input_ids);;  
    virtual Bool Calculate(GvNode *bn, GvPort *port, GvRun *r, GvCalc *calc)  
      // calculate all ports  
      if (!GvCalculateInValuesTable(bn, r, calc, ports)) return false;  
      // get the "Gradient" port  
      GvPort* portGradient = ports.in_values[0]->GetPort();  
      // get the "Gradient" data  
      Gradient* gradient = nullptr;  
      portGradient->GetDataInstance((const void*&)gradient, CUSTOMDATATYPE_GRADIENT, r);  
      // sample the gradient  
      if(gradient != nullptr)  
          InitRenderStruct irs(bn->GetDocument());  
          for(Int32 i = 0; i < 10; i++)  
              Vector color = gradient->CalcGradientPixel(Float(i) / 10.0);  
      return true;  
    // free data  
    virtual void FreeCalculation(GvNode *bn, GvCalc *calc)  
      GvFreeValuesTable(bn, ports);  

    best wishes,

  • On 22/05/2015 at 08:55, xxxxxxxx wrote:

    Hello Ama,

    was your question answered?

    Best wishes,

Log in to reply