private bool AttemptConvertVerticesAndIndices(glTFLoader.Schema.MeshPrimitive primitive, Rhino.Geometry.Mesh rhinoMesh) { if (!AttemptConvertVertices(primitive, rhinoMesh)) { return(false); } return(HandleIndices(primitive, rhinoMesh)); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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)); }