Material InitRender



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

    On 10/06/2010 at 00:10, xxxxxxxx wrote:

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

    ---------
    Hey,
    i have a Material Plugin that is depending on an other Material.
    How do i initialize the submaterial for rendering? If the submaterial is already in the Scene i can't call InitRender/FreeRender on this, because it is called by Cinema i guess. But if it is not in the Scene InitRender is not called on this Material, so i would need to call it.
    Am i missing something here?

    thanks,

    affa



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

    On 10/06/2010 at 01:44, xxxxxxxx wrote:

    Sorry I don't understand, you never call InitRender/FreeRender for a material only for channel shader (PluginShader). I am not sure what you are trying to achieve.

    cheers,
    Matthias



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

    On 10/06/2010 at 02:03, xxxxxxxx wrote:

    my Material has a link to an other BaseMaterial and evaluates the output of this.
    If the Material i'm referencing is not currently in the scene the CalcSurface function crashes.

    So i guessed it's because of the not called InitRender of the BaseMaterial



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

    On 10/06/2010 at 02:12, xxxxxxxx wrote:

    Is this working if both materials are in the scene? I must admint I never got it to work to sample a material within another material. So at the moment you know more about this topic than I :) Maybe you can post some simplified source code? I'll have to ask the developers.

    cheers,
    Matthias



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

    On 10/06/2010 at 02:37, xxxxxxxx wrote:

    yes it is working if the other material is in the scene.

    the code is rather simple, i have a Linked Material and am just calling CalcSurface of that.

    void MyMaterial::CalcSurface(BaseMaterial *mat, VolumeData *vd)
    {
    //linkedmat is
    linkedmat->CalcSurface(vd);
    //... do sth. with vd->col
    }

    if the material is not in the document i can call it's InitRender function via this workaround.

    LONG MyMaterial::InitRender(PluginMaterial *mat, InitRenderStruct *irs)
    {
    MaterialData* md = (MaterialData* )linkedmat->GetNodeData();
    if(md)
        md->InitRender(linkedmat, irs);
    }

    but i guess that is not that clean ;)
    as multiple calls to InitRender and FreeRender can happen then, it's kind of buggy
    and also it seems only to work for some materials as stated in the docs for GetNodeData()



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

    On 10/06/2010 at 03:30, xxxxxxxx wrote:

    Thanks for the code. There is a problem with calling NodeData members. From the "Stability and Testing" chapter of SDK docu:

    This Virtual Function Call will crash:
    PluginVideoPost \*node; for (node = renderdata->GetFirstVideoPost(); node; node=node->GetNext()) {   VideoPostData \*pVPData = (VideoPostData\*=)node->GetNodeData();   LONG info = pVPData->GetRenderInfo(); }

    • Beware of calling NodeData members!
    • pVPData can be NULL, check necessary
    • A plugin is not allowed to use the virtual function table of another plugin! This will only work with the same plugin, not over plugin boundaries

    To avoid crashes the call above must be replaced by:
    `  
    PluginVideoPost *node;
    for (node = renderdata->GetFirstVideoPost(); node; node=node->GetNext())
    {
      VideoPostData *pVPData = (VideoPostData*=)node->GetNodeData();
      if (!pVPData) continue;

    LONG info = ((pVPData->*((VIDEOPOSTPLUGIN* )C4DOS.Bl->RetrieveTableX(pVPData,0))->GetRenderInfo)(node);
    }
    `
    cheers,
    Matthias



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

    On 10/06/2010 at 03:59, xxxxxxxx wrote:

    yes, i'm aware of that, but md is mostly null anyways in my case. so that's not what's failing for me.

    I'd need to know what i shall do with materials that are not in the Scene but i need to evaluate for rendering. I guess i would need to initialize them in an other way?
    i also tried MSG_MULTI_MARKMATERIALS to tell Cinema which Materials i'm needing but that's only used in the "Remove unused Materials" i guess



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

    On 10/06/2010 at 06:33, xxxxxxxx wrote:

    Ok lets see if I understood it correctly.

    - You have two materials, MatA and MatB.
    - MatA is your plugin material.
    - MatB can be any of Cinema's materials.
    - There is a link to MatB in MatA.
    - MatA is evaluated during rendering, for instance it's attached to an object.
    - MatB is not assigned to any object.

    You want to know how to initialize MatB? If so you have to make sure to pass through any function call from MatA to MatB. For instance in MatA::InitRender you call MatB::InitRender. You already seem to do this. Important is to do this for every method of MaterialData. According to the developers that should do the trick.

    I will post if I find out more.

    cheers,
    Matthias



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

    On 10/06/2010 at 07:06, xxxxxxxx wrote:

    yes that is exactly what i'm doing.

    i'm passing every Method of my MaterialData on to the BaseMaterial MatB.
    But as i only have the BaseMaterial of MatB and not the MaterialData of MatB there is no InitRender function i could call.
    Thus the workaround from above with GetNodeData()->InitRender().

    But as GetNodeData() most times returns NULL for the BaseMaterials, i can't call InitRender then.

    I now tracked down that GetNodeData() always returns NULL for every Standard Cinema Material. All other Materials return their MaterialData (Baji, Banzi and so on).
    Why does the Standard Material return NULL? and what can i do about this?



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

    On 21/06/2010 at 05:55, xxxxxxxx wrote:

    FYI, currently it's not possible to sample standard materials because they are not derived from PluginMaterial.

    As for initializing materials, it should look something like this, where MATERIAL_LINK1 is the mateiral to be sampled:

      
    LONG ParticleVolume::InitRender(PluginMaterial *mat, InitRenderStruct *is)  
    {  
      BaseContainer *data = mat->GetDataInstance();  
      p_mat = data->GetMaterialLink(MATERIAL_LINK1, is->doc);  
      
      if (p_mat)  
      {  
          MaterialData *lmatdata = (MaterialData* )p_mat->GetNodeData();  
          if (lmatdata)  
          {  
              return (lmatdata->*((MATERIALPLUGIN* )C4DOS.Bl->RetrieveTableX(lmatdata,0))->InitRender)((PluginMaterial* )p_mat,is);  
          }  
      }  
      
      return LOAD_OK;  
    }  
      
    void ParticleVolume::FreeRender(PluginMaterial *mat)  
    {  
      if (p_mat)  
      {  
          MaterialData *lmatdata = (MaterialData* )p_mat->GetNodeData();  
          if (lmatdata)  
          {  
              (lmatdata->*((MATERIALPLUGIN* )C4DOS.Bl->RetrieveTableX(lmatdata,0))->FreeRender)((PluginMaterial* )p_mat);  
          }  
      }  
    }  
    

    cheers,
    Matthias



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

    On 21/06/2010 at 07:32, xxxxxxxx wrote:

    ok, too bad.
    thanks anyways for the info, so i'll have to come up with a different workflow i guess


Log in to reply