NetFrameInit() allocate layers



  • On 09/11/2015 at 09:04, xxxxxxxx wrote:

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

    ---------
    I'm having a problem allocating the multipass layers on the server side in NetFrameInit(). I want to add
    a grayscale layer (for a Z-Depth multipass), but that doesn't work as I expect it to. The z-depth layer on
    the client-side has a colors-per-pixel value of 1  (as I expect it to). These are allocated in
    VideoPostData::AllocateBuffers()  (i think?).

    Now, NetFrameInit()  seems to be handled pretty differently and I have to go over the procedure of
    allocating the multipass layers once again with a different interface (the MultipassBitmap ). Unfortunately,
    the Z-depth layer that I allocate always has a colors-per-pixel value of 3.?? This is the output that I get:

    @ Client Layers
        Z-Depth CPP: 1
        GI CPP: 3
        Normals CPP: 3
         CPP: 4
    @ Server Layers
        Z-Depth CPP: 3
        GI CPP: 3
        Normals CPP: 3
        Background CPP: 4
    

    Some code:

    /// --------------------------------------------------------------------------
    /// --------------------------------------------------------------------------
    Bool VrayBridgeVP::NetFrameInit(
      BaseVideoPost* node, BaseDocument* doc, RenderJob* job, Int32 assignedClients, 
      const NetRenderData* renderData, MultipassBitmap* frameBmp, BaseThread* bt,
      Int32& realdepth)
    {
      // << some initial stuff here >>
      
      // Allocate layers in the multipass bitmap respectively.
      for (Int32 i = 0; i < c4dSide.renderElement.GetCount(); ++i) {
        auto& element = c4dSide.renderElement[i];
        COLORMODE mode = COLORMODE_RGBf;
        switch (element.type) {
          case MpNode::NODE_TYPE_ZDEPTH:
          case MpNode::NODE_TYPE_OBJECTID:
          case MpNode::NODE_TYPE_COVERAGE:
            mode = COLORMODE_GRAY;
            break;
        }
        MultipassBitmap* layer = frameBmp->AddLayer(nullptr, mode, false);
      
        if (!layer) {
          print("[VB Team Render / ERROR]: Could not allocate Multipass", element.type);
          return false;
        }
        layer->SetUserID(element.type);
        layer->SetName(element.name);
        layer->SetSave(true);
      }
      return true;
    }
      
    /// --------------------------------------------------------------------------
    /// --------------------------------------------------------------------------
    void VrayBridgeVP::CollectServerLayers(maxon::BaseArray<VPBuffer*>& layers)
    {
      if (!this->_serverData.bmp) {
        print("[VP Team Render / ERROR]: Server Data not initialized on CollectServerLayers().");
        return;
      }
      Int32 const count = this->_serverData.bmp->GetLayerCount();
      for (Int32 index = 0; index < count; ++index) {
        MultipassBitmap* layer = this->_serverData.bmp->GetLayerNum(index);
        if (layer) layers.Append(reinterpret_cast<VPBuffer*>(layer));
        else {
          print("[VB Team Render / ERROR]: Server could not retrieve multipass layer", index);
        }
      }
      
      print("@ Server Layers");
      FOREACH(it, layers) {
        VPBuffer* buf = *it;
        print("   ", ((MultipassBitmap* ) buf)->GetParameter(MPBTYPE_NAME).GetString(), "CPP:", buf->GetCpp());
      }
    }
      
      
    /// --------------------------------------------------------------------------
    /// --------------------------------------------------------------------------
    void VrayBridgeVP::CollectClientLayers(maxon::BaseArray<VPBuffer*>& layers, Render* render)
    {
      VPBuffer* buffer = render->GetBuffer(VPBUFFER_RGBA, NOTOK);
      if (!buffer) {
        print("[VP Team Render / ERROR]: Could not get VPBUFFER_RGBA on client-side.");
        return;
      }
      
      // NOTE: We assume that in VrayBridgeVP::AllocateBuffer(), the ID of new
      //       buffers start at 2. Hopefully this doesn't break in the future.
      
      layers.Append(buffer);
      Int32 const count = this->c4dSide.renderElement.GetCount();
      for (Int32 index = 0; index < count; ++index) {
        // We offset by two as this is the starting ID for FX buffers.
        Int32 realId = index + 2;
      
        // Get the next matching buffer.
        VPBuffer* buffer = render->GetBuffer(VPBUFFER_POSTEFFECT, realId);
        if (!buffer)
          buffer = render->GetBuffer(VPBUFFER_POSTEFFECT_MUL, realId);
        
        // Insert the buffer at the beginning of the array.
        if (buffer) layers.Insert(0, buffer);
        else {
          auto const& element = this->c4dSide.renderElement[index];
          print("[VB Team Render / ERROR]: Client could not retrieve Buffer for Multipass", element.name);
        }
      }
      
      print("@ Client Layers");
      FOREACH (it, layers) {
        VPBuffer* buf = *it;
        print("   ", ((MultipassBitmap* ) buf)->GetParameter(MPBTYPE_NAME).GetString(), "CPP:", buf->GetCpp());
      }
    }
    

    Any hints are highly appreciated. Thanks,
    -Niklas



  • On 09/11/2015 at 09:12, xxxxxxxx wrote:

    Update  I've re-formulated my question.



  • On 10/11/2015 at 09:41, xxxxxxxx wrote:

    Hi Niklas,

    before answering, I'd like to note, that my experience with the render pipeline and Team render is yet pretty limited. So maybe the following will be absolute bogus or fail to hit your actual problem.

    If you use GetCpp() on the freshly created layers in NetFrameInit() you will see, that cpp is already three 
    The thing is GetCpp() does not take the color mode into account at all, instead cpp gets derived from the UserID. And since you are passing your own IDs it results always in three.
    For the following IDs it results in one:
    VPBUFFER_MAT_DIFFUSION, VPBUFFER_MAT_SPECULAR, VPBUFFER_OBJECTBUFFER, VPBUFFER_DEPTH, VPBUFFER_ATMOSPHERE_MUL, VPBUFFER_POSTEFFECT_MUL
    And for VPBUFFER_RGBA it's four.
    All other IDs will result in three.
    Not sure this is a problem for you, or if you could use the above IDs and store your own IDs in the SubId?
    That's all I'm saying before I risk my neck...



  • On 10/11/2015 at 09:50, xxxxxxxx wrote:

    Hey Andreas, thanks a lot for that information, that sure helps! :)
    I think I can use these VPBUFFER id's instead as I don't actually need the UserID. I'll give it a try!

    Edit: Christmas is early guys!  😄 Thanks again Andreas! I now use VPBUFFER_POSTEFFECT for normal
    layers and VPBUFFER_POSTEFFECT_MUL for Coverage, Object ID and Z-Depth passes, just as our
    AllocateBuffers() method does.



  • On 11/11/2015 at 00:26, xxxxxxxx wrote:

    Man, Christmas already? And I ain't got no presents, yet... 😲


Log in to reply