public void Deserialize(BinaryReader from)
        {
            // Bezier File Format :
            //   Header ('BZR ')            | sizeof(uint)
            //   Version (1.1)              | sizeof(uint)
            //   Regular patch count        | sizeof(uint)
            //   Quad patch count           | sizeof(uint)
            //   Triangle patch count       | sizeof(uint)

            this.Header = from.ReadStructure<BezierMesh.BezierHeader>();

            byte[] expectedHeader = {Convert.ToByte(' '), Convert.ToByte('R'), Convert.ToByte('Z'), Convert.ToByte('B')};

            if (BitConverter.IsLittleEndian)
                Array.Reverse(expectedHeader);

            if (Header.Header != BitConverter.ToInt32(expectedHeader,0) || (Header.Version != 0x0100 && Header.Version != 0x0101))
            {
                throw new ArgumentException("Incorrect input header or unsupported file format version");
            }

            //   Part 1.  Precomputed Control Points:
            //     Regular Patches:
            //       Bezier control points        | 16 * regularPatchCount * sizeof(float3)
            //       Texture coordinates          | 16 * regularPatchCount * sizeof(float2)
            //       Normal control points        | 16 * regularPatchCount * sizeof(float3)
            _RegularBezierControlPoints = new List<Vector3>(from.ReadStructure<Vector3>(Header.RegularPatchCount * 16));
            _RegularTextureCoordinates = new List<Vector2>(from.ReadStructure<Vector2>(Header.RegularPatchCount * 16));
            if (Header.Version == 0x0101)
            {
                // Load normals
                _RegularNormals = new List<Vector3>(from.ReadStructure<Vector3>(Header.RegularPatchCount * 16));
            } else
            {
                _RegularNormals = new List<Vector3>();
            }

            //     Quad Patches:
            //       Bezier control points        | 32 * quadPatchCount * sizeof(float3)
            //       Gregory control points       | 20 * quadPatchCount * sizeof(float3)
            //       Pm control points            | 24 * quadPatchCount * sizeof(float3)
            //       Texture coordinates          | 16 * quadPatchCount * sizeof(float2)
            //       Normal control points        | 16 * quadPatchCount * sizeof(float3)
            _QuadBezierControlPoints = new List<Vector3>(from.ReadStructure<Vector3>(Header.QuadPatchCount * 32));
            _QuadGregoryControlPoints = new List<Vector3>(from.ReadStructure<Vector3>(Header.QuadPatchCount * 20));
            _QuadPmControlPoints = new List<Vector3>(from.ReadStructure<Vector3>(Header.QuadPatchCount * 24));
            _QuadTextureCoordinates = new List<Vector2>(from.ReadStructure<Vector2>(Header.QuadPatchCount * 16));
            if (Header.Version == 0x0101)
            {
                // Load normals
                _QuadNormals = new List<Vector3>(from.ReadStructure<Vector3>(Header.QuadPatchCount * 16));
            }
            else
            {
                _QuadNormals = new List<Vector3>();
            }

            //     Triangle Patches:
            //       Gregory control points       | 15 * trianglePatchCount * sizeof(float3)
            //       Pm control points            | 19 * trianglePatchCount * sizeof(float3)
            //       Texture coordinates          | 12 * trianglePatchCount * sizeof(float2)
            _TriGregoryControlPoints = new List<Vector3>(from.ReadStructure<Vector3>(Header.TriPatchCount * 15));
            _TriPmControlPoints = new List<Vector3>(from.ReadStructure<Vector3>(Header.TriPatchCount * 19));
            _TriTextureCoordinates = new List<Vector2>(from.ReadStructure<Vector2>(Header.TriPatchCount * 12));

            //   Part 2. Stencils:
            //     faceTopologyCount              | sizeof(int)
            //     primitiveSize                  | sizeof(int)
            //     Bezier Stencil                 | faceTopologyCount * 32 * m_primitiveSize * sizeof(float)
            //     Gregory Stencil                | faceTopologyCount * 20 * m_primitiveSize * sizeof(float)
            //     regularFaceTopologyIndex       | regularPatchCount * sizeof(uint)
            //     regularVertexIndices           | 16 * regularPatchCount * sizeof(uint)
            //     regularStencilIndices          | 16 * regularPatchCount * sizeof(uint)
            //     quadVertexCount                | quadPatchCount * sizeof(uint)
            //     quadFaceTopologyIndex          | quadPatchCount * sizeof(uint)
            //     quadVertexIndices              | primitiveSize * quadpatchCount * sizeof(uint)
            //     quadStecilIndices              | primitiveSize * quadPatchCount * sizeof(uint)

            FaceTopologyCount = from.ReadInt32();
            PrimitiveSize = from.ReadInt32();

            _BezierStencil = new List<float>(from.ReadStructure<float>(FaceTopologyCount * 32 * PrimitiveSize));
            _GregoryStencil = new List<float>(from.ReadStructure<float>(FaceTopologyCount * 20 * PrimitiveSize));

            _RegularFaceTopologyIndex = new List<int>(from.ReadStructure<int>(Header.RegularPatchCount));
            _RegularVertexIndices = new List<int>(from.ReadStructure<int>(Header.RegularPatchCount * 16));
            _RegularStencilIndices = new List<int>(from.ReadStructure<int>(Header.RegularPatchCount * 16));

            _QuadFaceVertexCount = new List<int>(from.ReadStructure<int>(Header.QuadPatchCount));
            _QuadFaceTopologyIndex = new List<int>(from.ReadStructure<int>(Header.QuadPatchCount));
            _QuadVertexIndices = new List<int>(from.ReadStructure<int>(Header.QuadPatchCount * PrimitiveSize));
            _QuadStencilIndices = new List<int>(from.ReadStructure<int>(Header.QuadPatchCount * PrimitiveSize));

            //   Part 3. Input Mesh Topology:
            //     Vertex count                   | sizeof(uint)
            //     Vertices                       | vertexCount * sizeof(float3)
            //     Tangents/Bitangents            | vertexCount * 2 * sizeof(float3)
            //     Valences                       | vertexCount * sizeof(int)
            //     Texture coordinates            | vertexCount * sizeof(float2)
            //     Max valence                    | sizeof(uint)
            //     Regular face indices           | 4 * regularPatchCount * sizeof(uint)
            //     Quad face indices              | 4 * irregularpatchCount * sizeof(uint)
            //     Triangle face indices          | 3 * trianglePatchCount * sizeof(uint)

            VertexCount = from.ReadInt32();
            _Vertices = new List<Vector3>(from.ReadStructure<Vector3>(VertexCount));
            _Tangents = new List<Vector3>(from.ReadStructure<Vector3>(VertexCount * 2));
            _Valences = new List<int>(from.ReadStructure<int>(VertexCount));
            _TextureCoordinates = new List<Vector2>(from.ReadStructure<Vector2>(VertexCount));

            MaxValence = from.ReadInt32();

            _RegularFaceIndices = new List<int>(from.ReadStructure<int>(Header.RegularPatchCount * 4));
            _QuadFaceIndices = new List<int>(from.ReadStructure<int>(Header.QuadPatchCount * 4));
            _TriFaceIndices = new List<int>(from.ReadStructure<int>(Header.TriPatchCount * 3));

            #region Calculate the patch corner point indices relative to the patch

            // For each regular patch (bicubic bezier) set the indices for the
            // regular that define the face (i.e. the 4 corners)
            var regularIndices = new int[Header.RegularPatchCount * 4];
            for (int k = 0; k < Header.RegularPatchCount; k++)
            {
                for (int j = 0; j < 4; j++)
                {
                    for (int i = 0; i < 16; i++)
                    {
                        if (_RegularVertexIndices[k * 16 + i] == _RegularFaceIndices[k * 4 + j])
                        {
                            regularIndices[k * 4 + j] = i;
                        }
                    }
                }
            }

            // For an irregular patch (Gregory patch) set the indices for the
            // patch that define the face (i.e. the 4 corners)
            var quadIndices = new int[Header.QuadPatchCount * 4];
            for (int k = 0; k < Header.QuadPatchCount; k++)
            {
                for (int j = 0; j < 4; j++)
                {
                    for (int i = 0; i < PrimitiveSize; i++)
                    {
                        if (_QuadVertexIndices[k * PrimitiveSize + i] == _QuadFaceIndices[k * 4 + j])
                        {
                            quadIndices[k * 4 + j] = i;
                        }
                    }
                }
            }

            #endregion

            #region Compute input mesh indices

            var indexCount = 6 * Header.RegularPatchCount + 6 * Header.QuadPatchCount + 3 * Header.TriPatchCount;
            //var indexCount2 = 8 * Header.RegularPatchCount + 8 * Header.QuadPatchCount;

            var indices = new int[indexCount];

            int idx = 0;
            for (int i = 0; i < Header.RegularPatchCount; i++)
            {
                indices[idx++] = _RegularFaceIndices[4 * i + 2];
                indices[idx++] = _RegularFaceIndices[4 * i + 0];
                indices[idx++] = _RegularFaceIndices[4 * i + 1];

                indices[idx++] = _RegularFaceIndices[4 * i + 0];
                indices[idx++] = _RegularFaceIndices[4 * i + 2];
                indices[idx++] = _RegularFaceIndices[4 * i + 3];
            }
            for (int i = 0; i < Header.QuadPatchCount; i++)
            {
                indices[idx++] = _QuadFaceIndices[4 * i + 2];
                indices[idx++] = _QuadFaceIndices[4 * i + 0];
                indices[idx++] = _QuadFaceIndices[4 * i + 1];

                indices[idx++] = _QuadFaceIndices[4 * i + 0];
                indices[idx++] = _QuadFaceIndices[4 * i + 2];
                indices[idx++] = _QuadFaceIndices[4 * i + 3];
            }

            for (int i = 0; i < Header.TriPatchCount; i++)
            {
                indices[idx++] = _TriFaceIndices[4 * i + 2];
                indices[idx++] = _TriFaceIndices[4 * i + 0];
                indices[idx++] = _TriFaceIndices[4 * i + 1];
            }

            _Indices = new List<int>(indices);
            #endregion

            // Calculate the bounding box
            Vector3 minCorner = _Vertices[0];
            Vector3 maxCorner = _Vertices[0];

            foreach (var vertex in _Vertices)
            {
                if (minCorner.X > vertex.X) minCorner.X = vertex.X;
                else if (maxCorner.X < vertex.X) maxCorner.X = vertex.X;

                if (minCorner.Y > vertex.Y) minCorner.Y = vertex.Y;
                else if (maxCorner.Y < vertex.Y) maxCorner.Y = vertex.Y;

                if (minCorner.Z > vertex.Z) minCorner.Z = vertex.Z;
                else if (maxCorner.Z < vertex.Z) maxCorner.Z = vertex.Z;
            }

            Center = (minCorner + maxCorner) * 0.5f;
        }
        public void Deserialize(BinaryReader from)
        {
            // Bezier File Format :
            //   Header ('BZR ')            | sizeof(uint)
            //   Version (1.1)              | sizeof(uint)
            //   Regular patch count        | sizeof(uint)
            //   Quad patch count           | sizeof(uint)
            //   Triangle patch count       | sizeof(uint)

            this.Header = from.ReadStructure <BezierMesh.BezierHeader>();

            byte[] expectedHeader = { Convert.ToByte(' '), Convert.ToByte('R'), Convert.ToByte('Z'), Convert.ToByte('B') };

            if (BitConverter.IsLittleEndian)
            {
                Array.Reverse(expectedHeader);
            }

            if (Header.Header != BitConverter.ToInt32(expectedHeader, 0) || (Header.Version != 0x0100 && Header.Version != 0x0101))
            {
                throw new ArgumentException("Incorrect input header or unsupported file format version");
            }


            //   Part 1.  Precomputed Control Points:
            //     Regular Patches:
            //       Bezier control points        | 16 * regularPatchCount * sizeof(float3)
            //       Texture coordinates          | 16 * regularPatchCount * sizeof(float2)
            //       Normal control points        | 16 * regularPatchCount * sizeof(float3)
            _RegularBezierControlPoints = new List <Vector3>(from.ReadStructure <Vector3>(Header.RegularPatchCount * 16));
            _RegularTextureCoordinates  = new List <Vector2>(from.ReadStructure <Vector2>(Header.RegularPatchCount * 16));
            if (Header.Version == 0x0101)
            {
                // Load normals
                _RegularNormals = new List <Vector3>(from.ReadStructure <Vector3>(Header.RegularPatchCount * 16));
            }
            else
            {
                _RegularNormals = new List <Vector3>();
            }

            //     Quad Patches:
            //       Bezier control points        | 32 * quadPatchCount * sizeof(float3)
            //       Gregory control points       | 20 * quadPatchCount * sizeof(float3)
            //       Pm control points            | 24 * quadPatchCount * sizeof(float3)
            //       Texture coordinates          | 16 * quadPatchCount * sizeof(float2)
            //       Normal control points        | 16 * quadPatchCount * sizeof(float3)
            _QuadBezierControlPoints  = new List <Vector3>(from.ReadStructure <Vector3>(Header.QuadPatchCount * 32));
            _QuadGregoryControlPoints = new List <Vector3>(from.ReadStructure <Vector3>(Header.QuadPatchCount * 20));
            _QuadPmControlPoints      = new List <Vector3>(from.ReadStructure <Vector3>(Header.QuadPatchCount * 24));
            _QuadTextureCoordinates   = new List <Vector2>(from.ReadStructure <Vector2>(Header.QuadPatchCount * 16));
            if (Header.Version == 0x0101)
            {
                // Load normals
                _QuadNormals = new List <Vector3>(from.ReadStructure <Vector3>(Header.QuadPatchCount * 16));
            }
            else
            {
                _QuadNormals = new List <Vector3>();
            }

            //     Triangle Patches:
            //       Gregory control points       | 15 * trianglePatchCount * sizeof(float3)
            //       Pm control points            | 19 * trianglePatchCount * sizeof(float3)
            //       Texture coordinates          | 12 * trianglePatchCount * sizeof(float2)
            _TriGregoryControlPoints = new List <Vector3>(from.ReadStructure <Vector3>(Header.TriPatchCount * 15));
            _TriPmControlPoints      = new List <Vector3>(from.ReadStructure <Vector3>(Header.TriPatchCount * 19));
            _TriTextureCoordinates   = new List <Vector2>(from.ReadStructure <Vector2>(Header.TriPatchCount * 12));

            //   Part 2. Stencils:
            //     faceTopologyCount              | sizeof(int)
            //     primitiveSize                  | sizeof(int)
            //     Bezier Stencil                 | faceTopologyCount * 32 * m_primitiveSize * sizeof(float)
            //     Gregory Stencil                | faceTopologyCount * 20 * m_primitiveSize * sizeof(float)
            //     regularFaceTopologyIndex       | regularPatchCount * sizeof(uint)
            //     regularVertexIndices           | 16 * regularPatchCount * sizeof(uint)
            //     regularStencilIndices          | 16 * regularPatchCount * sizeof(uint)
            //     quadVertexCount                | quadPatchCount * sizeof(uint)
            //     quadFaceTopologyIndex          | quadPatchCount * sizeof(uint)
            //     quadVertexIndices              | primitiveSize * quadpatchCount * sizeof(uint)
            //     quadStecilIndices              | primitiveSize * quadPatchCount * sizeof(uint)

            FaceTopologyCount = from.ReadInt32();
            PrimitiveSize     = from.ReadInt32();

            _BezierStencil  = new List <float>(from.ReadStructure <float>(FaceTopologyCount * 32 * PrimitiveSize));
            _GregoryStencil = new List <float>(from.ReadStructure <float>(FaceTopologyCount * 20 * PrimitiveSize));

            _RegularFaceTopologyIndex = new List <int>(from.ReadStructure <int>(Header.RegularPatchCount));
            _RegularVertexIndices     = new List <int>(from.ReadStructure <int>(Header.RegularPatchCount * 16));
            _RegularStencilIndices    = new List <int>(from.ReadStructure <int>(Header.RegularPatchCount * 16));

            _QuadFaceVertexCount   = new List <int>(from.ReadStructure <int>(Header.QuadPatchCount));
            _QuadFaceTopologyIndex = new List <int>(from.ReadStructure <int>(Header.QuadPatchCount));
            _QuadVertexIndices     = new List <int>(from.ReadStructure <int>(Header.QuadPatchCount * PrimitiveSize));
            _QuadStencilIndices    = new List <int>(from.ReadStructure <int>(Header.QuadPatchCount * PrimitiveSize));

            //   Part 3. Input Mesh Topology:
            //     Vertex count                   | sizeof(uint)
            //     Vertices                       | vertexCount * sizeof(float3)
            //     Tangents/Bitangents            | vertexCount * 2 * sizeof(float3)
            //     Valences                       | vertexCount * sizeof(int)
            //     Texture coordinates            | vertexCount * sizeof(float2)
            //     Max valence                    | sizeof(uint)
            //     Regular face indices           | 4 * regularPatchCount * sizeof(uint)
            //     Quad face indices              | 4 * irregularpatchCount * sizeof(uint)
            //     Triangle face indices          | 3 * trianglePatchCount * sizeof(uint)

            VertexCount         = from.ReadInt32();
            _Vertices           = new List <Vector3>(from.ReadStructure <Vector3>(VertexCount));
            _Tangents           = new List <Vector3>(from.ReadStructure <Vector3>(VertexCount * 2));
            _Valences           = new List <int>(from.ReadStructure <int>(VertexCount));
            _TextureCoordinates = new List <Vector2>(from.ReadStructure <Vector2>(VertexCount));

            MaxValence = from.ReadInt32();

            _RegularFaceIndices = new List <int>(from.ReadStructure <int>(Header.RegularPatchCount * 4));
            _QuadFaceIndices    = new List <int>(from.ReadStructure <int>(Header.QuadPatchCount * 4));
            _TriFaceIndices     = new List <int>(from.ReadStructure <int>(Header.TriPatchCount * 3));

            #region Calculate the patch corner point indices relative to the patch

            // For each regular patch (bicubic bezier) set the indices for the
            // regular that define the face (i.e. the 4 corners)
            var regularIndices = new int[Header.RegularPatchCount * 4];
            for (int k = 0; k < Header.RegularPatchCount; k++)
            {
                for (int j = 0; j < 4; j++)
                {
                    for (int i = 0; i < 16; i++)
                    {
                        if (_RegularVertexIndices[k * 16 + i] == _RegularFaceIndices[k * 4 + j])
                        {
                            regularIndices[k * 4 + j] = i;
                        }
                    }
                }
            }

            // For an irregular patch (Gregory patch) set the indices for the
            // patch that define the face (i.e. the 4 corners)
            var quadIndices = new int[Header.QuadPatchCount * 4];
            for (int k = 0; k < Header.QuadPatchCount; k++)
            {
                for (int j = 0; j < 4; j++)
                {
                    for (int i = 0; i < PrimitiveSize; i++)
                    {
                        if (_QuadVertexIndices[k * PrimitiveSize + i] == _QuadFaceIndices[k * 4 + j])
                        {
                            quadIndices[k * 4 + j] = i;
                        }
                    }
                }
            }

            #endregion

            #region Compute input mesh indices

            var indexCount = 6 * Header.RegularPatchCount + 6 * Header.QuadPatchCount + 3 * Header.TriPatchCount;
            //var indexCount2 = 8 * Header.RegularPatchCount + 8 * Header.QuadPatchCount;

            var indices = new int[indexCount];

            int idx = 0;
            for (int i = 0; i < Header.RegularPatchCount; i++)
            {
                indices[idx++] = _RegularFaceIndices[4 * i + 2];
                indices[idx++] = _RegularFaceIndices[4 * i + 0];
                indices[idx++] = _RegularFaceIndices[4 * i + 1];

                indices[idx++] = _RegularFaceIndices[4 * i + 0];
                indices[idx++] = _RegularFaceIndices[4 * i + 2];
                indices[idx++] = _RegularFaceIndices[4 * i + 3];
            }
            for (int i = 0; i < Header.QuadPatchCount; i++)
            {
                indices[idx++] = _QuadFaceIndices[4 * i + 2];
                indices[idx++] = _QuadFaceIndices[4 * i + 0];
                indices[idx++] = _QuadFaceIndices[4 * i + 1];

                indices[idx++] = _QuadFaceIndices[4 * i + 0];
                indices[idx++] = _QuadFaceIndices[4 * i + 2];
                indices[idx++] = _QuadFaceIndices[4 * i + 3];
            }

            for (int i = 0; i < Header.TriPatchCount; i++)
            {
                indices[idx++] = _TriFaceIndices[4 * i + 2];
                indices[idx++] = _TriFaceIndices[4 * i + 0];
                indices[idx++] = _TriFaceIndices[4 * i + 1];
            }

            _Indices = new List <int>(indices);
            #endregion

            // Calculate the bounding box
            Vector3 minCorner = _Vertices[0];
            Vector3 maxCorner = _Vertices[0];

            foreach (var vertex in _Vertices)
            {
                if (minCorner.X > vertex.X)
                {
                    minCorner.X = vertex.X;
                }
                else if (maxCorner.X < vertex.X)
                {
                    maxCorner.X = vertex.X;
                }

                if (minCorner.Y > vertex.Y)
                {
                    minCorner.Y = vertex.Y;
                }
                else if (maxCorner.Y < vertex.Y)
                {
                    maxCorner.Y = vertex.Y;
                }

                if (minCorner.Z > vertex.Z)
                {
                    minCorner.Z = vertex.Z;
                }
                else if (maxCorner.Z < vertex.Z)
                {
                    maxCorner.Z = vertex.Z;
                }
            }

            Center = (minCorner + maxCorner) * 0.5f;
        }