NAV Navbar
c#

Vertex Deformation Guide

The vertex deformation fits a local asset to a specific didimo.

The asset must be available on the application side; then its vertex are extracted and sent to didimo API, so that it can be deformed.

The result from the API must replace/update the vertex information in the local application.

File Format

   // Check the code snippets below to convert the asset vertex to byte array and back

32bit float array little-endian where each float represents a coordinate value of a vertex, and each 3 floats represents a vertex; the resulting file must have a multiple of 12 bytes of size in the following format: XXXXYYYYZZZZXXXXYYYYZZZZXXXXYYYYZZZZ

Step By Step

    // These snippets allow for convertion of the asset vertex to byte array
    // and to update the model vertex with resulting byte array from the asset deformer 

    // in this class deformableAsset is a GameObject
    // which contains in its hierarchy all the MeshFilters of the asset 

    //Get vertex byte array from deformableAsset 
    byte[] GetVertexPositions()
        {
            byte[] vertex_bytes = new byte[0];
            try
            {
                Stream stream = new MemoryStream();
                using (BinaryWriter bw = new BinaryWriter(stream))
                {
                    // Unity uses meters, but on the didimo pipeline we use centimeters
                    float scaleFactor = 0.01f;
                    MeshFilter[] meshList = deformableAsset.GetComponentsInChildren<MeshFilter>();
                    Vector3[] vertexList;
                    int byte_length = 0;
                    foreach (MeshFilter mf in meshList)
                    {
                        vertexList = mf.mesh.vertices;
                        Array.Resize(ref vertex_bytes, 3 * 4 * vertexList.Length);
                        for (int i = 0; i < vertexList.Length; i++)
                        {
                            vertexList[i] /= scaleFactor;
                            // In unity, the x coordinate is inverted
                            InsertAsBytes(vertex_bytes, ref byte_length, vertexList[i].x * -1);
                            InsertAsBytes(vertex_bytes, ref byte_length, vertexList[i].y);
                            InsertAsBytes(vertex_bytes, ref byte_length, vertexList[i].z);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.LogError(ex);
            }
            return vertex_bytes;
        }
        void InsertAsBytes(byte[] array, ref int position, float value)
        {
            byte[] byteValue = BitConverter.GetBytes(value);
            if (!BitConverter.IsLittleEndian)
            {
                Array.Reverse(byteValue); // Convert big endian to little endian
            }
            byteValue.CopyTo(array, position);
            position += byteValue.Length;
        }


    //Update deformableAsset vertex position from byte array  
    void SetVertexPositions(byte[] vertex)
    {
        MeshFilter[] meshList = deformableAsset.GetComponentsInChildren<MeshFilter>();
        int arrayPosition = 0;
        foreach (MeshFilter mf in meshList)
        {
            Vector3[] vertexList = new Vector3[mf.mesh.vertexCount];
            //vertexList = mf.mesh.vertices;
            for (int i = 0; i < mf.mesh.vertexCount; i++)
            {
                SetVector3FromNextBytes(vertex, ref arrayPosition, ref vertexList[i]);
            }
            mf.mesh.vertices = vertexList;
        }
    }
    public void SetVector3FromNextBytes(byte[] bytes, ref int position, ref Vector3 result)
    {
        // Unity uses meters, but on the pipeline we use centimeters
        float scaleFactor = 0.01f;
        byte[] value = new byte[4];
        Array.Copy(bytes, position, value, 0, 4);
        // In unity, the x coordinate is inverted
        result.x = BytesToFloat(value) * -1;
        position += 4;
        Array.Copy(bytes, position, value, 0, 4);
        result.y = BytesToFloat(value);
        position += 4;
        Array.Copy(bytes, position, value, 0, 4);
        result.z = BytesToFloat(value);
        position += 4;
        result *= scaleFactor;
    }

    public float BytesToFloat(byte[] bytes)
    {
        if (!BitConverter.IsLittleEndian)
        {
            Array.Reverse(bytes); // Convert big endian to little endian
        }
        float myFloat = BitConverter.ToSingle(bytes, 0);
        return myFloat;
    }

  1. Load the asset model
  2. Extract vertex information and convert to 32bit float array little-endian (see example snippet below).
  3. Call the vertex deform endpoint POST /v2/didimo/<didimo_key>/execute/vertexdeform with the bytes payload.
  4. Poll the status endpoint GET /v2/didimo/:key/status with key returned by the previous endpoint until resulting status is "done".
  5. Download the resulting vertex bytes using the download endpoint GET /v2/didimo/:key/downlaod. Those bytes are on the same order as the ones sent to the API.
  6. Update/replace vertex in model
c#