Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
// from c4dtoa_symols.h
#define MSG_C4DTOA_RENDER_TO_BUFFER_INIT 1041303
#define MSG_C4DTOA_RENDER_TO_BUFFER_START 1041295
#define MSG_C4DTOA_RENDER_TO_BUFFER_PREPARE_BUCKET 1041302
#define MSG_C4DTOA_RENDER_TO_BUFFER_WRITE_BUCKET 1041297
#define MSG_C4DTOA_RENDER_TO_BUFFER_END 1041296
#define MSG_C4DTOA_RENDER_TO_BUFFER_FINISH 1041304
// from arnold_renderer.h
#define C4DTOA_RENDERTOBUFFER_NUM_BUFFERS 100             // [Int32] Number of render output buffers (AOVs).
#define C4DTOA_RENDERTOBUFFER_XRES 101                    // [Int32] Resolution width.
#define C4DTOA_RENDERTOBUFFER_YRES 102                    // [Int32] Resolution height.
#define C4DTOA_RENDERTOBUFFER_BUFFER_BUCKET_XO 103        // [Int32] The top-left x coordinate of the bucket.
#define C4DTOA_RENDERTOBUFFER_BUFFER_BUCKET_YO 104        // [Int32] The top-left y coordinate of the bucket.
#define C4DTOA_RENDERTOBUFFER_BUFFER_BUCKET_SIZE_X 105    // [Int32] The width of the bucket.
#define C4DTOA_RENDERTOBUFFER_BUFFER_BUCKET_SIZE_Y 106    // [Int32] The height of the bucket.
#define C4DTOA_RENDERTOBUFFER_BUFFER_FIRST 1000           // [BaseContainer] Each buffer is stored in a BaseContainer started from this ID.
#define C4DTOA_RENDERTOBUFFER_BUFFER_NAME 100             // [String] Name of the AOV (e.g. RGBA, diffuse_direct, etc.)
#define C4DTOA_RENDERTOBUFFER_BUFFER_DATA_TYPE 101        // [Int32] Data type of the AOV. (e.g. AI_TYPE_FLOAT, etc.)
#define C4DTOA_RENDERTOBUFFER_BUFFER_BUCKET_DATA 102      // [Void*] Memory buffer of the AOV. The pixels are stored line-by-line from the top left corner.
// from ai_params.h
#define AI_TYPE_INT           0x01  // Int32
#define AI_TYPE_UINT          0x02  // UInt32
#define AI_TYPE_FLOAT         0x04  // Float32
#define AI_TYPE_RGB           0x05  // 3 * Float32
#define AI_TYPE_RGBA          0x06  // 4 * Float32
#define AI_TYPE_VECTOR        0x07  // 3 * Float32
#define AI_TYPE_VECTOR2       0x09  // 2 * Float32
#define AI_TYPE_UNDEFINED     0xFF  
 
class BitmapSaver
{
private:
    int m_xres, m_yres;
    std::map<std::string, BaseBitmap*> m_bitmaps;

public:
    ~BitmapSaver()
    {
        Free();
    }

    BitmapSaver* GetBitmap(const String& aovNameStr)
    {
        char aovName[256];
        aovNameStr.GetCString(aovName, 256);
        std::map<std::string, BaseBitmap*>::iterator it = m_bitmaps.find(aovName);
        if (it != m_bitmaps.end())
            return it->second;
        return nullptr;
    }

    std::map<std::string, BaseBitmap*> GetBitmaps()
    {
        return m_bitmaps;
    }

    ///
    /// Allocates the bitmaps.
    ///
    void Init(BaseContainer* data)
    {
        Int32 xres = data->GetInt32(C4DTOA_RENDERTOBUFFER_XRES);
        Int32 yres = data->GetInt32(C4DTOA_RENDERTOBUFFER_YRES);

        // initialize the bitmaps
        Int32 numBuffers = data->GetInt32(C4DTOA_RENDERTOBUFFER_NUM_BUFFERS);
        for (int i = 0; i < numBuffers; i++)
        {
            BaseContainer* aovData = data->GetContainerInstance(C4DTOA_RENDERTOBUFFER_BUFFER_FIRST + i);
            const String& aovNameStr = aovData->GetString(C4DTOA_RENDERTOBUFFER_BUFFER_NAME);
            char aovName[256];
            aovNameStr.GetCString(aovName, 256);
            
            // allocate the bitmap
            GePrintF("Allocate bitmap of %s: %d x %d", aovName, xres, yres);
            bitmap = BaseBitmap::Alloc();
            bitmap->Init(xres, yres);
            m_bitmaps[aovName] = bitmap;
        }
    }

    ///
    /// Writes the buckets to the bitmaps.
    ///
    void WriteBucket(BaseContainer* data)
    {
        int bucket_xo = data->GetInt32(C4DTOA_RENDERTOBUFFER_BUFFER_BUCKET_XO);
        int bucket_yo = data->GetInt32(C4DTOA_RENDERTOBUFFER_BUFFER_BUCKET_YO);
        int bucket_size_x = data->GetInt32(C4DTOA_RENDERTOBUFFER_BUFFER_BUCKET_SIZE_X);
        int bucket_size_y = data->GetInt32(C4DTOA_RENDERTOBUFFER_BUFFER_BUCKET_SIZE_Y);

        //GePrintF("Write bucket: %d %d | %d %d", bucket_xo, bucket_yo, bucket_size_x, bucket_size_y);
        int bitmapBufferSize = COLORBYTES_RGBf * bucket_size_x;
        UChar* bitmapBuffer = NewMemClear(UChar, bitmapBufferSize);


        // copy the bucket data to the bitmap
        Int32 numBuffers = data->GetInt32(C4DTOA_RENDERTOBUFFER_NUM_BUFFERS);
        for (Int32 i = 0; i < numBuffers; i++)
        {
            BaseBitmap* bitmap = GetBitmap(aovNameStr);
            if (!bitmap)
                continue;
 
            BaseContainer* aovData = data->GetContainerInstance(C4DTOA_RENDERTOBUFFER_BUFFER_FIRST + i);
            const String& aovNameStr = aovData->GetString(C4DTOA_RENDERTOBUFFER_BUFFER_NAME);
            int dataType = aovData->GetInt32(C4DTOA_RENDERTOBUFFER_BUFFER_DATA_TYPE);

            unsigned int pixelIndex = 0;
            for (int y = 0; y < bucket_size_y; y++)
            {
                PIX_F* bi = (PIX_F*)bitmapBuffer;
                for (int x = 0; x < bucket_size_x; x++)
                {
                    switch (dataType)
                    {
                        case AI_TYPE_RGBA:
                        {
                            Float32* bucketData = (Float32*)aovData->GetVoid(C4DTOA_RENDERTOBUFFER_BUFFER_BUCKET_DATA);
                            bi[0] = bucketData[4 * pixelIndex + 0];
                            bi[1] = bucketData[4 * pixelIndex + 1];
                            bi[2] = bucketData[4 * pixelIndex + 2];
                            break;
                        }
                        case AI_TYPE_RGB:
                        case AI_TYPE_VECTOR:
                        {
                            Float32* bucketData = (Float32*)aovData->GetVoid(C4DTOA_RENDERTOBUFFER_BUFFER_BUCKET_DATA);
                            bi[0] = bucketData[3 * pixelIndex + 0];
                            bi[1] = bucketData[3 * pixelIndex + 1];
                            bi[2] = bucketData[3 * pixelIndex + 2];
                            break;
                        }
                        case AI_TYPE_VECTOR2:
                        {
                            Float32* bucketData = (Float32*)aovData->GetVoid(C4DTOA_RENDERTOBUFFER_BUFFER_BUCKET_DATA);
                            bi[0] = bucketData[2 * pixelIndex + 0];
                            bi[1] = bucketData[2 * pixelIndex + 1];
                            bi[2] = 0.0f;
                            break;
                        }
                        case AI_TYPE_FLOAT:
                        {
                            Float32* bucketData = (Float32*)aovData->GetVoid(C4DTOA_RENDERTOBUFFER_BUFFER_BUCKET_DATA);
                            bi[0] = bucketData[pixelIndex];
                            bi[1] = bucketData[pixelIndex];
                            bi[2] = bucketData[pixelIndex];
                            break;
                        }
                        case AI_TYPE_INT:
                        {
                            Int32* bucketData = (Int32*)aovData->GetVoid(C4DTOA_RENDERTOBUFFER_BUFFER_BUCKET_DATA);
                            bi[0] = (Float32)bucketData[pixelIndex];
                            bi[1] = (Float32)bucketData[pixelIndex];
                            bi[2] = (Float32)bucketData[pixelIndex];
                            break;
                        }
                        case AI_TYPE_UINT:
                        {
                            UInt32* bucketData = (UInt32*)aovData->GetVoid(C4DTOA_RENDERTOBUFFER_BUFFER_BUCKET_DATA);
                            bi[0] = (Float32)bucketData[pixelIndex];
                            bi[1] = (Float32)bucketData[pixelIndex];
                            bi[2] = (Float32)bucketData[pixelIndex];
                            break;
                        }
                    }

                    bitmap->SetPixelCnt(bucket_xo, bucket_yo + y, bucket_size_x, bitmapBuffer, COLORBYTES_RGBf, COLORMODE_RGBf, PIXELCNT_0);
                    bi += 3;
                    pixelIndex++;
                }
            }
        }
        DeleteMem(bitmapBuffer);
    }

    void Free()
    {
        for (std::map<std::string, BaseBitmap*>::iterator it = m_bitmaps.begin(); it != m_bitmaps.end(); it++)
        {
            BaseBitmap* bitmap = it->second;
            BaseBitmap::Free(bitmap);
        }
        m_bitmaps.clear();
    }
};


BitmapSaver bitmapSaver;
 
Bool PluginMessage(Int32 id, void *data)
{
    switch (id)
    {   
        ///////////
        // render to buffer callbacks
        ///////////

        // render init
        case MSG_C4DTOA_RENDER_TO_BUFFER_INIT:
        {
            GePrintF("Render to Buffer init message received");
            break;
        }

        // render iteration start
        case MSG_C4DTOA_RENDER_TO_BUFFER_START:
        {
            GePrintF("Render to Buffer start message received");
            bitmapSaver.Init((BaseContainer*)data);
            break;
        }

        // write bucket
        case MSG_C4DTOA_RENDER_TO_BUFFER_WRITE_BUCKET:
        {
            GePrintF("Render to Buffer write bucket message received");
            bitmapSaver.WriteBucket((BaseContainer*)data);
            break;
        }

        // render iteration end
        case MSG_C4DTOA_RENDER_TO_BUFFER_END:
        {
            GePrintF("Render to Buffer end message received");
            bitmapSaver.Free((BaseContainer*)data);
            break;
        }

        // render finish
        case MSG_C4DTOA_RENDER_TO_BUFFER_FINISH:
        {
            GePrintF("Render to Buffer finish message received");
            break;
        }
    }

    return FALSE;
}

...

© 2020-2021 Autodesk. All Rights Reserved / website terms / privacy/cookies / ccpa settings