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, }); }
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)); }
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, }); }
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)); }
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)); }
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); }
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); }