This demo code shows how to read out data from vertex buffer and index buffer of a ManualObject.
It was written in C# (for Mogre), but should be easy to port to C++. If anybody do so, please publish the C++ code on this wiki page.

The interesting code is in section DATA GRABBING. The code before and behind is just for testing and displaying.
Don't forget the unsafe declaration to avoid compiler errors.

To convert the (local) vertex positions to world positions, look to the code comments and apply the conversion.

Written by user Beauty in 2011 and tested with Ogre/Mogre 1.7.
help For questions or bug reports use this forum topic.

public static unsafe void test_GetManualObjectRawData(SceneManager smgr)
{

    //-- CREATE TEST OBJECT --

    ManualObject manOb = smgr.CreateManualObject("manob_test_" + Guid.NewGuid());

    manOb.Begin("Core/NodeMaterial", RenderOperation.OperationTypes.OT_POINT_LIST);
    manOb.Position(new Vector3(0, 0, 0));
    manOb.Position(new Vector3(1, 1, 1));
    manOb.End();

    manOb.Begin("Core/NodeMaterial", RenderOperation.OperationTypes.OT_LINE_LIST);
    manOb.Position(new Vector3(2, 2, 2));
    manOb.Position(new Vector3(3, 3, 3));
    manOb.End();

    manOb.Begin("Core/NodeMaterial", RenderOperation.OperationTypes.OT_LINE_STRIP);
    manOb.Position(new Vector3(11, 11, 11));
    manOb.Position(new Vector3(22, 22, 22));
    manOb.Position(new Vector3(33, 33, 33));
    manOb.Index(2);
    manOb.Index(1);
    manOb.Index(0);
    manOb.Index(2);
    manOb.End();

    // storage lists for test output
    List<Vector3> posList = new List<Vector3>();
    List<UInt64> indexList = new List<UInt64>();



    //-- DATA GRABBING --

    RenderOperation moData = new RenderOperation(); // access to vertex and index buffer
        
    // loop for each section
    for (UInt32 i = 0;   i < manOb.NumSections;    i++)
    {
        manOb.GetSection(i).GetRenderOperation(moData);

        //-- read vertex data --

        VertexElement posEl = moData.vertexData.vertexDeclaration.FindElementBySemantic(VertexElementSemantic.VES_POSITION);
        HardwareVertexBufferSharedPtr vBuff = moData.vertexData.vertexBufferBinding.GetBuffer(posEl.Source);

        byte* pVertex = (byte*)vBuff.Lock(HardwareBuffer.LockOptions.HBL_READ_ONLY);
        float* pReal;

        for (Int32 j = 0;   j < moData.vertexData.vertexCount;   j++)
        {
            posEl.BaseVertexPointerToElement(pVertex, &pReal);
            Vector3 vertexPos = new Vector3(pReal[0], pReal[1], pReal[2]);

            // CONVERSION TO WORLD POSITIONS:
            // Grabb world properties of parent SceneNode
            // by _getDerivedPosition() / _getDerivedOrientation() / _getDerivedScale()
            // and apply this calculation:
            // vertexPos = (orientation * (vertexPos * scale)) + position;

            posList.Add(vertexPos);
            pVertex += vBuff.VertexSize;
        }
                
        vBuff.Unlock();            


        //-- read index data --

        if (moData.useIndexes)
        {
            HardwareIndexBufferSharedPtr iBuff = moData.indexData.indexBuffer;

            // UNPORTED line of C++ code (because ibuf.IsNull() doesn't exist in C#)
            //     if( ibuf.isNull() ) continue
            //     need to check if index buffer is valid (which will be not if the mesh doesn't have triangles like a pointcloud)

            uint* pLong = (uint*)iBuff.Lock(HardwareBuffer.LockOptions.HBL_READ_ONLY);
            ushort* pShort = (ushort*)pLong;

            for (int k = 0;   k < moData.indexData.indexCount;   k++)
            {
                UInt64 index;

                if (iBuff.Type == HardwareIndexBuffer.IndexType.IT_32BIT)  // if 32bit indexes
                    index = (UInt64)pLong[k];
                else
                    index = (UInt64)pShort[k];

                indexList.Add(index);
            }

            iBuff.Unlock();
        } // if




        //-- read vertex data by index order --
        //   Note: This block is independent from the previous blocks

        if (moData.useIndexes)
        {
            //VertexElement 
            posEl = moData.vertexData.vertexDeclaration.FindElementBySemantic(VertexElementSemantic.VES_POSITION);
            //HardwareVertexBufferSharedPtr 
            vBuff = moData.vertexData.vertexBufferBinding.GetBuffer(posEl.Source);

            //byte* 
            pVertex = (byte*)vBuff.Lock(HardwareBuffer.LockOptions.HBL_READ_ONLY);
            //float* pReal;

            byte* pStartVertex = pVertex;

            HardwareIndexBufferSharedPtr iBuff = moData.indexData.indexBuffer;

            // UNPORTED line of C++ code (because ibuf.IsNull() doesn't exist in C#)
            //     if( ibuf.isNull() ) continue
            //     need to check if index buffer is valid (which will be not if the mesh doesn't have triangles like a pointcloud)

            uint* pLong = (uint*)iBuff.Lock(HardwareBuffer.LockOptions.HBL_READ_ONLY);
            ushort* pShort = (ushort*)pLong;

            for (int k = 0; k < moData.indexData.indexCount; k++)
            {
                UInt64 index;

                if (iBuff.Type == HardwareIndexBuffer.IndexType.IT_32BIT)  // if 32bit indexes
                    index = (UInt64)pLong[k];
                else
                    index = (UInt64)pShort[k];

                pVertex = pStartVertex + (vBuff.VertexSize * index);

                posEl.BaseVertexPointerToElement(pVertex, &pReal);
                Vector3 vertexPos = new Vector3(pReal[0], pReal[1], pReal[2]);
                posByIndexList.Add(vertexPos);

            }

            iBuff.Unlock();
            vBuff.Unlock();

        } // if



        //-- TEST OUTPUT --
            
        Console.WriteLine("--- new section of ManualObject ---");
        Console.WriteLine("Render operation type:  " + moData.operationType);
        foreach(Vector3 vertexPos in posList)
            Console.WriteLine("Vertex position:  " + vertexPos);
        foreach (UInt64 ind in indexList)
            Console.WriteLine("Index:  " + ind);
        foreach (Vector3 vertexPos in posByIndexList)
            Console.WriteLine("Vertex by index:  " + vertexPos);
        if (indexList.Count == 0)
            Console.WriteLine("No indexes");

        posList.Clear();
        indexList.Clear();
        posByIndexList.Clear();

    } // for each section

    Console.WriteLine("\n");

}