Exemple #1
0
        private bool AttemptConvertVerticesAndIndices(glTFLoader.Schema.MeshPrimitive primitive, Rhino.Geometry.Mesh rhinoMesh)
        {
            if (!AttemptConvertVertices(primitive, rhinoMesh))
            {
                return(false);
            }

            return(HandleIndices(primitive, rhinoMesh));
        }
Exemple #2
0
 Rhino.Geometry.Mesh GetMesh(glTFLoader.Schema.MeshPrimitive primitive)
 {
     if (primitive.Extensions != null && primitive.Extensions.TryGetValue(glTFExtensions.KHR_draco_mesh_compression.Tag, out object value))
     {
         return(ConvertDraco(value.ToString()));
     }
     else
     {
         return(ConvertPrimtive(primitive));
     }
 }
        private Material LoadMaterial(glTFLoader.Schema.MeshPrimitive primitive, MaterialLoader materialLoader)
        {
            var materialIndex = primitive.Material;

            if (materialIndex.HasValue)
            {
                return(materialLoader.LoadMaterial(materialIndex.Value));
            }
            else
            {
                return(materialLoader.LoadDefaultMaterial());
            }
        }
        private GltfMesh LoadSubMesh(glTFLoader.Schema.MeshPrimitive primitive)
        {
            var mesh = new GltfMesh();

            // Consider moving this logic into another class (SubMeshLoader.cs?)
            foreach (var attribute in primitive.Attributes)
            {
                LoadMeshAttribute(mesh, attribute.Key, attribute.Value);
            }

            LoadMeshAttribute(mesh, "INDEX", primitive.Indices.GetValueOrDefault());

            return(mesh);
        }
Exemple #5
0
        Rhino.Geometry.Mesh ConvertPrimtive(glTFLoader.Schema.MeshPrimitive primitive)
        {
            Rhino.Geometry.Mesh rhinoMesh = new Rhino.Geometry.Mesh();

            if (!AttemptConvertVerticesAndIndices(primitive, rhinoMesh)) //Only part that is required
            {
                return(null);
            }

            if (!AttemptConvertNormals(primitive, rhinoMesh))
            {
                rhinoMesh.RebuildNormals();
            }

            AttemptConvertTextureCoordinates(primitive, rhinoMesh);

            AttemptConvertVertexColors(primitive, rhinoMesh);

            return(rhinoMesh);
        }
Exemple #6
0
        private bool HandleIndices(glTFLoader.Schema.MeshPrimitive primitive, Rhino.Geometry.Mesh rhinoMesh)
        {
            if (primitive.Indices.HasValue)
            {
                return(AttemptConvertIndices(primitive, rhinoMesh));
            }
            else if (primitive.Mode == glTFLoader.Schema.MeshPrimitive.ModeEnum.TRIANGLES)
            {
                return(HandleTrianglesMode(rhinoMesh));
            }
            else if (primitive.Mode == glTFLoader.Schema.MeshPrimitive.ModeEnum.TRIANGLE_STRIP)
            {
                return(HandleTriangleStripMode(rhinoMesh));
            }
            else if (primitive.Mode == glTFLoader.Schema.MeshPrimitive.ModeEnum.TRIANGLE_FAN)
            {
                return(HandleTriangleFanMode(rhinoMesh));
            }

            return(false);
        }
Exemple #7
0
        private List <glTFLoader.Schema.MeshPrimitive> GetPrimitives()
        {
            List <glTFLoader.Schema.MeshPrimitive> primitives = new List <glTFLoader.Schema.MeshPrimitive>();

            foreach (Mesh rhinoMesh in exportData.Meshes)
            {
                PreprocessMesh(rhinoMesh);

                if (options.UseDracoCompression)
                {
                    if (!SetDracoGeometryInfo(rhinoMesh))
                    {
                        continue;
                    }
                }

                bool exportNormals            = ExportNormals(rhinoMesh);
                bool exportTextureCoordinates = ExportTextureCoordinates(rhinoMesh);
                bool exportVertexColors       = ExportVertexColors(rhinoMesh);

                glTFLoader.Schema.MeshPrimitive primitive = new glTFLoader.Schema.MeshPrimitive()
                {
                    Attributes = new Dictionary <string, int>(),
                };

                int vertexAccessorIdx = GetVertexAccessor(rhinoMesh.Vertices);

                primitive.Attributes.Add(Constants.PositionAttributeTag, vertexAccessorIdx);

                int indicesAccessorIdx = GetIndicesAccessor(rhinoMesh.Faces, rhinoMesh.Vertices.Count);

                primitive.Indices = indicesAccessorIdx;

                if (exportNormals)
                {
                    int normalsAccessorIdx = GetNormalsAccessor(rhinoMesh.Normals);

                    primitive.Attributes.Add(Constants.NormalAttributeTag, normalsAccessorIdx);
                }

                if (exportTextureCoordinates)
                {
                    int textureCoordinatesAccessorIdx = GetTextureCoordinatesAccessor(rhinoMesh.TextureCoordinates);

                    primitive.Attributes.Add(Constants.TexCoord0AttributeTag, textureCoordinatesAccessorIdx);
                }

                if (exportVertexColors)
                {
                    int vertexColorsAccessorIdx = GetVertexColorAccessor(rhinoMesh.VertexColors);

                    primitive.Attributes.Add(Constants.VertexColorAttributeTag, vertexColorsAccessorIdx);
                }

                if (options.UseDracoCompression)
                {
                    glTFExtensions.KHR_draco_mesh_compression dracoCompressionObject = new glTFExtensions.KHR_draco_mesh_compression();

                    dracoCompressionObject.BufferView = currentGeometryInfo.BufferViewIndex;

                    dracoCompressionObject.Attributes.Add(Constants.PositionAttributeTag, currentGeometryInfo.VertexAttributePosition);

                    if (exportNormals)
                    {
                        dracoCompressionObject.Attributes.Add(Constants.NormalAttributeTag, currentGeometryInfo.NormalAttributePosition);
                    }

                    if (exportTextureCoordinates)
                    {
                        dracoCompressionObject.Attributes.Add(Constants.TexCoord0AttributeTag, currentGeometryInfo.TextureCoordinatesAttributePosition);
                    }

                    if (exportVertexColors)
                    {
                        dracoCompressionObject.Attributes.Add(Constants.VertexColorAttributeTag, currentGeometryInfo.VertexColorAttributePosition);
                    }

                    primitive.Extensions = new Dictionary <string, object>();

                    primitive.Extensions.Add(glTFExtensions.KHR_draco_mesh_compression.Tag, dracoCompressionObject);
                }

                primitive.Material = materialIndex;

                primitives.Add(primitive);
            }

            return(primitives);
        }
Exemple #8
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);
        }
Exemple #9
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);
        }
Exemple #10
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);
        }
Exemple #11
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);
        }
Exemple #12
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);
        }
Exemple #13
0
        public static string Serialize(Rhino.RhinoDoc doc)
        {
            var model = new glTFLoader.Schema.Gltf();

            #region Iterate through objects in doc

            foreach (Rhino.DocObjects.RhinoObject o in doc.Objects)
            {
                var mesh     = new Rhino.Geometry.Mesh();
                var glTFMesh = new glTFLoader.Schema.Mesh();

                switch (o.ObjectType)
                {
                case Rhino.DocObjects.ObjectType.Extrusion:
                case Rhino.DocObjects.ObjectType.SubD:
                case Rhino.DocObjects.ObjectType.Brep:
                    mesh.Append(o.GetMeshes(Rhino.Geometry.MeshType.Default));
                    break;

                case Rhino.DocObjects.ObjectType.Mesh:
                    mesh = o.Geometry as Rhino.Geometry.Mesh;
                    break;

                default:
                    Rhino.RhinoApp.WriteLine("Exporting {0} is not supported.", o.ObjectType);
                    break;
                }

                // do something with mesh

                glTFMesh.Name = o.Name;

                var primitive = new glTFLoader.Schema.MeshPrimitive();

                // Faces

                var accessor = new glTFLoader.Schema.Accessor();
                accessor.Type = glTFLoader.Schema.Accessor.TypeEnum.SCALAR;

                var indices = new List <int>();

                foreach (var face in mesh.Faces)
                {
                    if (face.IsTriangle)
                    {
                        indices.Add(face.A);
                        indices.Add(face.B);
                        indices.Add(face.C);
                    }
                    if (face.IsQuad)
                    {
                        indices.Add(face.A);
                        indices.Add(face.B);
                        indices.Add(face.C);
                        indices.Add(face.D);
                    }
                }

                accessor.Count = indices.Count;

                int min = 0;
                int max = 0;

                foreach (var id in indices)
                {
                    if (id < min)
                    {
                        min = id;
                    }
                    if (id > max)
                    {
                        max = id;
                    }
                }

                accessor.Min = new float [] { min };
                accessor.Max = new float [] { max };



                /*
                 *  var faceIds = accessorData[mp.Indices.Value];
                 *  var faces = new List<MeshFace>();
                 *
                 *  for (int i = 0; i <= faceIds.Count - 3; i = i + 3)
                 *      faces.Add(new MeshFace(faceIds[i], faceIds[i + 1], faceIds[i + 2]));
                 *
                 *  meshPart.Faces.AddFaces(faces);
                 */
            }

            #endregion

            return(glTFLoader.Interface.SerializeModel(model));
        }