Example #1
0
        Rhino.Geometry.Mesh ConvertDraco(string text)
        {
            var khr_draco = Newtonsoft.Json.JsonConvert.DeserializeObject <glTFExtensions.KHR_draco_mesh_compression>(text);

            if (khr_draco == null)
            {
                return(null);
            }

            glTFLoader.Schema.BufferView view = converter.GetBufferView(khr_draco.BufferView);

            byte[] buffer = converter.GetBuffer(view.Buffer);

            if (buffer == null)
            {
                return(null);
            }

            int offset = view.ByteOffset;
            int length = view.ByteLength;

            byte[] dracoBytes = new byte[length];
            Array.Copy(buffer, offset, dracoBytes, 0, length);

            return(Rhino.FileIO.DracoCompression.DecompressByteArray(dracoBytes) as Rhino.Geometry.Mesh);
        }
        private glTFLoader.Schema.Image GetImageFromBitmapText(Bitmap bitmap)
        {
            byte[] imageBytes = GetImageBytes(bitmap);

            var textureBuffer = new glTFLoader.Schema.Buffer();

            textureBuffer.Uri        = Constants.TextBufferHeader + Convert.ToBase64String(imageBytes);
            textureBuffer.ByteLength = imageBytes.Length;

            int textureBufferIdx = dummy.Buffers.AddAndReturnIndex(textureBuffer);

            // Create bufferviews
            var textureBufferView = new glTFLoader.Schema.BufferView()
            {
                Buffer     = textureBufferIdx,
                ByteOffset = 0,
                ByteLength = textureBuffer.ByteLength,
            };
            int textureBufferViewIdx = dummy.BufferViews.AddAndReturnIndex(textureBufferView);

            return(new glTFLoader.Schema.Image()
            {
                BufferView = textureBufferViewIdx,
                MimeType = glTFLoader.Schema.Image.MimeTypeEnum.image_png,
            });
        }
        private glTFLoader.Schema.Image GetImageFromFileText(string fileName)
        {
            byte[] imageBytes = GetImageBytesFromFile(fileName);

            var textureBuffer = new glTFLoader.Schema.Buffer()
            {
                Uri        = Constants.TextBufferHeader + Convert.ToBase64String(imageBytes),
                ByteLength = imageBytes.Length,
            };

            int textureBufferIdx = dummy.Buffers.AddAndReturnIndex(textureBuffer);

            var textureBufferView = new glTFLoader.Schema.BufferView()
            {
                Buffer     = textureBufferIdx,
                ByteOffset = 0,
                ByteLength = textureBuffer.ByteLength,
            };
            int textureBufferViewIdx = dummy.BufferViews.AddAndReturnIndex(textureBufferView);

            return(new glTFLoader.Schema.Image()
            {
                BufferView = textureBufferViewIdx,
                MimeType = glTFLoader.Schema.Image.MimeTypeEnum.image_png,
            });
        }
        private glTFLoader.Schema.Image GetImageFromFileBinary(string fileName)
        {
            byte[] imageBytes       = GetImageBytesFromFile(fileName);
            int    imageBytesOffset = (int)binaryBuffer.Count;

            binaryBuffer.AddRange(imageBytes);

            var textureBufferView = new glTFLoader.Schema.BufferView()
            {
                Buffer     = 0,
                ByteOffset = imageBytesOffset,
                ByteLength = imageBytes.Length,
            };
            int textureBufferViewIdx = dummy.BufferViews.AddAndReturnIndex(textureBufferView);

            return(new glTFLoader.Schema.Image()
            {
                BufferView = textureBufferViewIdx,
                MimeType = glTFLoader.Schema.Image.MimeTypeEnum.image_png,
            });
        }
Example #5
0
        private int?GetIndicesBufferView(MeshFaceList faces, int verticesCount, out float min, out float max, out int indicesCount)
        {
            if (options.UseDracoCompression)
            {
                min          = currentGeometryInfo.IndicesMin;
                max          = currentGeometryInfo.IndicesMax;
                indicesCount = currentGeometryInfo.IndicesCount;
                return(null);
            }

            int bufferIndex = 0;
            int byteOffset  = 0;
            int byteLength  = 0;

            if (binary)
            {
                byte[] bytes = GetIndicesBytes(faces, out indicesCount);
                byteLength = bytes.Length;
                byteOffset = binaryBuffer.Count;
                binaryBuffer.AddRange(bytes);
            }
            else
            {
                bufferIndex = GetIndicesBuffer(faces, out indicesCount, out byteLength);
            }

            glTFLoader.Schema.BufferView indicesBufferView = new glTFLoader.Schema.BufferView()
            {
                Buffer     = bufferIndex,
                ByteOffset = byteOffset,
                ByteLength = byteLength,
                Target     = glTFLoader.Schema.BufferView.TargetEnum.ELEMENT_ARRAY_BUFFER,
            };

            min = 0;
            max = verticesCount - 1;

            return(dummy.BufferViews.AddAndReturnIndex(indicesBufferView));
        }
Example #6
0
        private int?GetVertexBufferView(MeshVertexList vertices, out Point3d min, out Point3d max, out int countVertices)
        {
            if (options.UseDracoCompression)
            {
                min           = currentGeometryInfo.VerticesMin;
                max           = currentGeometryInfo.VerticesMax;
                countVertices = currentGeometryInfo.VerticesCount;
                return(null);
            }

            int buffer     = 0;
            int byteLength = 0;
            int byteOffset = 0;

            if (binary)
            {
                byte[] bytes = GetVertexBytes(vertices, out min, out max);
                buffer     = 0;
                byteLength = bytes.Length;
                byteOffset = binaryBuffer.Count;
                binaryBuffer.AddRange(bytes);
            }
            else
            {
                buffer = GetVertexBuffer(vertices, out min, out max, out byteLength);
            }

            glTFLoader.Schema.BufferView vertexBufferView = new glTFLoader.Schema.BufferView()
            {
                Buffer     = buffer,
                ByteOffset = byteOffset,
                ByteLength = byteLength,
                Target     = glTFLoader.Schema.BufferView.TargetEnum.ARRAY_BUFFER,
            };

            countVertices = vertices.Count;

            return(dummy.BufferViews.AddAndReturnIndex(vertexBufferView));
        }
        private glTFLoader.Schema.Image GetImageFromBitmapBinary(Bitmap bitmap)
        {
            byte[] imageBytes       = GetImageBytes(bitmap);
            int    imageBytesOffset = (int)binaryBuffer.Count;

            binaryBuffer.AddRange(imageBytes);

            // Create bufferviews
            var textureBufferView = new glTFLoader.Schema.BufferView()
            {
                Buffer     = 0,
                ByteOffset = imageBytesOffset,
                ByteLength = imageBytes.Length,
            };
            int textureBufferViewIdx = dummy.BufferViews.AddAndReturnIndex(textureBufferView);

            return(new glTFLoader.Schema.Image()
            {
                BufferView = textureBufferViewIdx,
                MimeType = glTFLoader.Schema.Image.MimeTypeEnum.image_png,
            });
        }
Example #8
0
        int?GetTextureCoordinatesBufferView(MeshTextureCoordinateList textureCoordinates, out Point2f min, out Point2f max, out int countCoordinates)
        {
            if (options.UseDracoCompression)
            {
                min = currentGeometryInfo.TexCoordsMin;
                max = currentGeometryInfo.TexCoordsMax;
                countCoordinates = currentGeometryInfo.TexCoordsCount;
                return(null);
            }

            int buffer     = 0;
            int byteLength = 0;
            int byteOffset = 0;

            if (binary)
            {
                byte[] bytes = GetTextureCoordinatesBytes(textureCoordinates, out min, out max);
                byteLength = bytes.Length;
                byteOffset = binaryBuffer.Count;
                binaryBuffer.AddRange(bytes);
            }
            else
            {
                buffer = GetTextureCoordinatesBuffer(textureCoordinates, out min, out max, out byteLength);
            }

            glTFLoader.Schema.BufferView textureCoordinatesBufferView = new glTFLoader.Schema.BufferView()
            {
                Buffer     = buffer,
                ByteLength = byteLength,
                ByteOffset = byteOffset,
                Target     = glTFLoader.Schema.BufferView.TargetEnum.ARRAY_BUFFER,
            };

            countCoordinates = textureCoordinates.Count;

            return(dummy.BufferViews.AddAndReturnIndex(textureCoordinatesBufferView));
        }
Example #9
0
        int?GetNormalsBufferView(MeshVertexNormalList normals, out Vector3f min, out Vector3f max, out int normalsCount)
        {
            if (options.UseDracoCompression)
            {
                min          = currentGeometryInfo.NormalsMin;
                max          = currentGeometryInfo.NormalsMax;
                normalsCount = currentGeometryInfo.NormalsCount;
                return(null);
            }

            int buffer     = 0;
            int byteOffset = 0;
            int byteLength = 0;

            if (binary)
            {
                byte[] bytes = GetNormalsBytes(normals, out min, out max);
                byteLength = bytes.Length;
                byteOffset = binaryBuffer.Count;
                binaryBuffer.AddRange(bytes);
            }
            else
            {
                buffer = GetNormalsBuffer(normals, out min, out max, out byteLength);
            }

            glTFLoader.Schema.BufferView normalsBufferView = new glTFLoader.Schema.BufferView()
            {
                Buffer     = buffer,
                ByteLength = byteLength,
                ByteOffset = byteOffset,
                Target     = glTFLoader.Schema.BufferView.TargetEnum.ARRAY_BUFFER,
            };

            normalsCount = normals.Count;

            return(dummy.BufferViews.AddAndReturnIndex(normalsBufferView));
        }
Example #10
0
        public DracoGeometryInfo AddDracoGeometry(DracoCompression dracoCompression)
        {
            var dracoGeoInfo = new DracoGeometryInfo();

            string fileName = Path.GetTempFileName();

            try
            {
                dracoCompression.Write(fileName);

                dracoGeoInfo.VertexAttributePosition             = dracoCompression.VertexAttributePosition;
                dracoGeoInfo.NormalAttributePosition             = dracoCompression.NormalAttributePosition;
                dracoGeoInfo.TextureCoordinatesAttributePosition = dracoCompression.TextureCoordinatesAttributePosition;
                dracoGeoInfo.VertexColorAttributePosition        = dracoCompression.VertexColorAttributePosition;

                byte[] dracoBytes = GetDracoBytes(fileName);

                WriteDracoBytes(dracoBytes, out dracoGeoInfo.BufferIndex, out dracoGeoInfo.ByteOffset, out dracoGeoInfo.ByteLength);

                glTFLoader.Schema.BufferView compMeshBufferView = new glTFLoader.Schema.BufferView()
                {
                    Buffer     = dracoGeoInfo.BufferIndex,
                    ByteOffset = dracoGeoInfo.ByteOffset,
                    ByteLength = dracoGeoInfo.ByteLength,
                };

                dracoGeoInfo.BufferViewIndex = dummy.BufferViews.AddAndReturnIndex(compMeshBufferView);

                dracoGeoInfo.ByteLength = dracoBytes.Length;

                var geo = DracoCompression.DecompressFile(fileName);
                if (geo.ObjectType == Rhino.DocObjects.ObjectType.Mesh)
                {
                    var mesh = (Rhino.Geometry.Mesh)geo;

                    // Vertices Stats
                    dracoGeoInfo.VerticesCount = mesh.Vertices.Count;
                    dracoGeoInfo.VerticesMin   = new Point3d(mesh.Vertices.Min());
                    dracoGeoInfo.VerticesMax   = new Point3d(mesh.Vertices.Max());

                    dracoGeoInfo.IndicesCount = mesh.Faces.TriangleCount;
                    dracoGeoInfo.IndicesMin   = 0;
                    dracoGeoInfo.IndicesMax   = dracoGeoInfo.VerticesCount - 1;

                    dracoGeoInfo.NormalsCount = mesh.Normals.Count;
                    dracoGeoInfo.NormalsMin   = mesh.Normals.Min();
                    dracoGeoInfo.NormalsMax   = mesh.Normals.Max();

                    // TexCoord Stats
                    dracoGeoInfo.TexCoordsCount = mesh.TextureCoordinates.Count;
                    if (dracoGeoInfo.TexCoordsCount > 0)
                    {
                        dracoGeoInfo.TexCoordsMin = mesh.TextureCoordinates.Min();
                        dracoGeoInfo.TexCoordsMax = mesh.TextureCoordinates.Max();
                    }

                    dracoGeoInfo.VertexColorCount = mesh.VertexColors.Count;
                    dracoGeoInfo.VertexColorMin   = Color4f.Black;
                    dracoGeoInfo.VertexColorMax   = Color4f.White;

                    dracoGeoInfo.Success = true;
                }
                geo.Dispose();
                dracoCompression.Dispose();
            }
            finally
            {
                File.Delete(fileName);
            }

            return(dracoGeoInfo);
        }
Example #11
0
        private bool AttemptConvertVertexColors(glTFLoader.Schema.MeshPrimitive primitive, Rhino.Geometry.Mesh rhinoMesh)
        {
            if (!primitive.Attributes.TryGetValue(VertexColorAttributeTag, out int vertexColorAccessorIndex))
            {
                return(false);
            }

            glTFLoader.Schema.Accessor vertexColorAccessor = converter.GetAccessor(vertexColorAccessorIndex);

            if (vertexColorAccessor == null)
            {
                return(false);
            }

            glTFLoader.Schema.BufferView vertexColorBufferView = converter.GetBufferView(vertexColorAccessor.BufferView);

            if (vertexColorBufferView == null)
            {
                return(false);
            }

            byte[] vertexColorBuffer = converter.GetBuffer(vertexColorBufferView.Buffer);

            if (vertexColorBuffer == null)
            {
                return(false);
            }

            int vertexColorOffset = vertexColorAccessor.ByteOffset + vertexColorBufferView.ByteOffset;

            int vertexColorStride = vertexColorBufferView.ByteStride.HasValue ? vertexColorBufferView.ByteStride.Value : TotalStride(vertexColorAccessor.ComponentType, vertexColorAccessor.Type);

            int vertexColorComponentCount = ComponentsCount(vertexColorAccessor.Type);

            int vertexColorComponentSize = ComponentSize(vertexColorAccessor.ComponentType);

            List <float> vertexColors = new List <float>();

            for (int i = 0; i < vertexColorAccessor.Count; i++)
            {
                int vertexColorIndex = vertexColorOffset + i * vertexColorStride;

                for (int j = 0; j < vertexColorComponentCount; j++)
                {
                    int location = vertexColorIndex + j * vertexColorComponentSize;

                    float channelColor = 0.0f;

                    if (vertexColorAccessor.ComponentType == glTFLoader.Schema.Accessor.ComponentTypeEnum.FLOAT)
                    {
                        channelColor = BitConverter.ToSingle(vertexColorBuffer, location);
                    }
                    else if (vertexColorAccessor.ComponentType == glTFLoader.Schema.Accessor.ComponentTypeEnum.UNSIGNED_SHORT)
                    {
                        ushort value = BitConverter.ToUInt16(vertexColorBuffer, location);
                        channelColor = (float)value / (float)ushort.MaxValue;
                    }
                    else if (vertexColorAccessor.ComponentType == glTFLoader.Schema.Accessor.ComponentTypeEnum.UNSIGNED_BYTE)
                    {
                        byte value = vertexColorBuffer[location];
                        channelColor = (float)value / (float)byte.MaxValue;
                    }

                    vertexColors.Add(channelColor);
                }
            }

            int countVertexColors = vertexColors.Count / vertexColorComponentCount;

            for (int i = 0; i < countVertexColors; i++)
            {
                int index = i * vertexColorComponentCount;

                if (vertexColorAccessor.Type == glTFLoader.Schema.Accessor.TypeEnum.VEC3)
                {
                    float r = GltfUtils.Clamp(vertexColors[index + 0], 0.0f, 1.0f);
                    float g = GltfUtils.Clamp(vertexColors[index + 1], 0.0f, 1.0f);
                    float b = GltfUtils.Clamp(vertexColors[index + 2], 0.0f, 1.0f);

                    Rhino.Display.Color4f color = new Rhino.Display.Color4f(r, g, b, 1.0f);

                    rhinoMesh.VertexColors.Add(color.AsSystemColor());
                }
                else if (vertexColorAccessor.Type == glTFLoader.Schema.Accessor.TypeEnum.VEC4)
                {
                    float r = GltfUtils.Clamp(vertexColors[index + 0], 0.0f, 1.0f);
                    float g = GltfUtils.Clamp(vertexColors[index + 1], 0.0f, 1.0f);
                    float b = GltfUtils.Clamp(vertexColors[index + 2], 0.0f, 1.0f);
                    float a = GltfUtils.Clamp(vertexColors[index + 3], 0.0f, 1.0f);

                    Rhino.Display.Color4f color = new Rhino.Display.Color4f(r, g, b, a);

                    rhinoMesh.VertexColors.Add(color.AsSystemColor());
                }
            }

            return(true);
        }
Example #12
0
        private bool AttemptConvertTextureCoordinates(glTFLoader.Schema.MeshPrimitive primitive, Rhino.Geometry.Mesh rhinoMesh)
        {
            if (!primitive.Attributes.TryGetValue(TexCoord0AttributeTag, out int texCoordsAttributeAccessorIndex))
            {
                return(false);
            }

            glTFLoader.Schema.Accessor texCoordsAccessor = converter.GetAccessor(texCoordsAttributeAccessorIndex);

            if (texCoordsAccessor == null)
            {
                return(false);
            }

            glTFLoader.Schema.BufferView texCoordsBufferView = converter.GetBufferView(texCoordsAccessor.BufferView);

            if (texCoordsBufferView == null)
            {
                return(false);
            }

            byte[] texCoordsBuffer = converter.GetBuffer(texCoordsBufferView.Buffer);

            if (texCoordsBuffer == null)
            {
                return(false);
            }

            int texCoordsOffset = texCoordsAccessor.ByteOffset + texCoordsBufferView.ByteOffset;

            int texCoordsStride = texCoordsBufferView.ByteStride.HasValue ? texCoordsBufferView.ByteStride.Value : TotalStride(texCoordsAccessor.ComponentType, texCoordsAccessor.Type);

            int texCoordsComponentCount = ComponentsCount(texCoordsAccessor.Type);

            int texCoordsComponentSize = ComponentSize(texCoordsAccessor.ComponentType);

            List <float> texCoords = new List <float>();

            for (int i = 0; i < texCoordsAccessor.Count; i++)
            {
                int texCoordsIndex = texCoordsOffset + i * texCoordsStride;

                for (int j = 0; j < texCoordsComponentCount; j++)
                {
                    int location = texCoordsIndex + j * texCoordsComponentSize;

                    float coordinate = 0.0f;

                    if (texCoordsAccessor.ComponentType == glTFLoader.Schema.Accessor.ComponentTypeEnum.FLOAT)
                    {
                        coordinate = BitConverter.ToSingle(texCoordsBuffer, location);
                    }
                    else if (texCoordsAccessor.ComponentType == glTFLoader.Schema.Accessor.ComponentTypeEnum.UNSIGNED_BYTE)
                    {
                        byte byteVal = texCoordsBuffer[location];
                        coordinate = (float)byteVal / (float)byte.MaxValue;
                    }
                    else if (texCoordsAccessor.ComponentType == glTFLoader.Schema.Accessor.ComponentTypeEnum.UNSIGNED_SHORT)
                    {
                        ushort shortValue = BitConverter.ToUInt16(texCoordsBuffer, location);
                        coordinate = (float)shortValue / (float)ushort.MaxValue;
                    }

                    texCoords.Add(coordinate);
                }
            }

            int coordinates = texCoords.Count / 2;

            for (int i = 0; i < coordinates; i++)
            {
                int index = i * 2;

                Rhino.Geometry.Point2f coordinate = new Rhino.Geometry.Point2f(texCoords[index + 0], texCoords[index + 1]);

                rhinoMesh.TextureCoordinates.Add(coordinate);
            }

            return(true);
        }
Example #13
0
        private bool AttemptConvertNormals(glTFLoader.Schema.MeshPrimitive primitive, Rhino.Geometry.Mesh rhinoMesh)
        {
            if (!primitive.Attributes.TryGetValue(NormalAttributeTag, out int normalAttributeAccessorIndex))
            {
                return(false);
            }

            glTFLoader.Schema.Accessor normalsAccessor = converter.GetAccessor(normalAttributeAccessorIndex);

            if (normalsAccessor == null)
            {
                return(false);
            }

            glTFLoader.Schema.BufferView normalsView = converter.GetBufferView(normalsAccessor.BufferView);

            if (normalsView == null)
            {
                return(false);
            }

            byte[] normalsBuffer = converter.GetBuffer(normalsView.Buffer);

            if (normalsBuffer == null)
            {
                return(false);
            }

            int normalsOffset = normalsView.ByteOffset + normalsAccessor.ByteOffset;

            int normalsStride = normalsView.ByteStride.HasValue ? normalsView.ByteStride.Value : TotalStride(normalsAccessor.ComponentType, normalsAccessor.Type);

            int normalsComponentsCount = ComponentsCount(normalsAccessor.Type);

            int normalsComponentSize = ComponentSize(normalsAccessor.ComponentType);

            List <float> normalsFloats = new List <float>();

            for (int i = 0; i < normalsAccessor.Count; i++)
            {
                int normalsIndex = normalsOffset + i * normalsStride;

                for (int j = 0; j < normalsComponentsCount; j++)
                {
                    int location = normalsIndex + j * normalsComponentSize;

                    float normalComponent = BitConverter.ToSingle(normalsBuffer, location);

                    normalsFloats.Add(normalComponent);
                }
            }

            int normals = normalsFloats.Count / 3;

            for (int i = 0; i < normals; i++)
            {
                int index = i * 3;
                rhinoMesh.Normals.Add(normalsFloats[index], normalsFloats[index + 1], normalsFloats[index + 2]);
            }

            return(true);
        }
Example #14
0
        private bool AttemptConvertVertices(glTFLoader.Schema.MeshPrimitive primitive, Rhino.Geometry.Mesh rhinoMesh)
        {
            glTFLoader.Schema.Accessor vertexAcessor = null;

            if (!primitive.Attributes.TryGetValue(PositionAttributeTag, out int vertexAcessorIndex))
            {
                return(false);
            }

            vertexAcessor = converter.GetAccessor(vertexAcessorIndex);

            if (vertexAcessor == null)
            {
                return(false);
            }

            glTFLoader.Schema.BufferView vertexView = converter.GetBufferView(vertexAcessor.BufferView);

            if (vertexView == null)
            {
                return(false);
            }

            byte[] vertexBuffer = converter.GetBuffer(vertexView.Buffer);

            if (vertexBuffer == null)
            {
                return(false);
            }

            int vertexOffset          = vertexAcessor.ByteOffset + vertexView.ByteOffset;
            int vertexStride          = vertexView.ByteStride.HasValue ? vertexView.ByteStride.Value : TotalStride(vertexAcessor.ComponentType, vertexAcessor.Type);
            int vertexComponentsCount = ComponentsCount(vertexAcessor.Type);
            int vertexComponentSize   = ComponentSize(vertexAcessor.ComponentType);

            List <float> floats = new List <float>();

            for (int i = 0; i < vertexAcessor.Count; i++)
            {
                int index = vertexOffset + vertexStride * i;

                for (int j = 0; j < vertexComponentsCount; j++)
                {
                    int offset = index + j * vertexComponentSize;

                    float f = BitConverter.ToSingle(vertexBuffer, offset);

                    floats.Add(f);
                }
            }

            int vertices = floats.Count / 3;

            for (int i = 0; i < vertices; i++)
            {
                int index = i * 3;
                rhinoMesh.Vertices.Add((double)floats[index], (double)floats[index + 1], (double)floats[index + 2]);
            }

            return(true);
        }
Example #15
0
        private bool AttemptConvertIndices(glTFLoader.Schema.MeshPrimitive primitive, Rhino.Geometry.Mesh rhinoMesh)
        {
            glTFLoader.Schema.Accessor indicesAccessor = converter.GetAccessor(primitive.Indices);

            if (indicesAccessor == null)
            {
                return(false);
            }

            glTFLoader.Schema.BufferView indicesView = converter.GetBufferView(indicesAccessor.BufferView);

            if (indicesView == null)
            {
                return(false);
            }

            byte[] indicesBuffer = converter.GetBuffer(indicesView.Buffer);

            if (indicesBuffer == null)
            {
                return(false);
            }

            int indicesOffset          = indicesAccessor.ByteOffset + indicesView.ByteOffset;
            int indicesStride          = indicesView.ByteStride.HasValue ? indicesView.ByteStride.Value : TotalStride(indicesAccessor.ComponentType, indicesAccessor.Type);
            int indicesComponentsCount = ComponentsCount(indicesAccessor.Type);
            int indicesComponentSize   = ComponentSize(indicesAccessor.ComponentType);

            List <uint> indices = new List <uint>();

            for (int i = 0; i < indicesAccessor.Count; i++)
            {
                int index = indicesOffset + indicesStride * i;

                for (int j = 0; j < indicesComponentsCount; j++)
                {
                    int location = index + j * indicesComponentSize;

                    if (indicesAccessor.ComponentType == glTFLoader.Schema.Accessor.ComponentTypeEnum.UNSIGNED_BYTE)
                    {
                        byte b = indicesBuffer[location];
                        indices.Add(b);
                    }
                    else if (indicesAccessor.ComponentType == glTFLoader.Schema.Accessor.ComponentTypeEnum.UNSIGNED_SHORT)
                    {
                        ushort s = BitConverter.ToUInt16(indicesBuffer, location);
                        indices.Add(s);
                    }
                    else if (indicesAccessor.ComponentType == glTFLoader.Schema.Accessor.ComponentTypeEnum.UNSIGNED_INT)
                    {
                        uint u = BitConverter.ToUInt32(indicesBuffer, location);
                        indices.Add(u);
                    }
                }
            }

            int faces = indices.Count / 3;

            for (int i = 0; i < faces; i++)
            {
                int index = i * 3;

                int indexOne   = (int)indices[index + 0];
                int indexTwo   = (int)indices[index + 1];
                int indexThree = (int)indices[index + 2];

                if (ValidFace(indexOne, indexTwo, indexThree, rhinoMesh.Vertices.Count))
                {
                    rhinoMesh.Faces.AddFace(indexOne, indexTwo, indexThree);
                }
            }

            return(true);
        }