private bool SetDracoGeometryInfo(Mesh rhinoMesh) { var dracoComp = DracoCompression.Compress( rhinoMesh, new DracoCompressionOptions() { VertexColorFormat = DracoColorFormat.RGBA, CompressionLevel = options.DracoCompressionLevel, IncludeNormals = ExportNormals(rhinoMesh), IncludeTextureCoordinates = ExportTextureCoordinates(rhinoMesh), IncludeVertexColors = ExportVertexColors(rhinoMesh), PositionQuantizationBits = options.DracoQuantizationBitsPosition, NormalQuantizationBits = options.DracoQuantizationBitsNormal, TextureCoordintateQuantizationBits = options.DracoQuantizationBitsTexture } ); currentGeometryInfo = AddDracoGeometry(dracoComp); return(currentGeometryInfo.Success); }
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); }
public DracoGeometryInfo AddDracoGeometry(DracoCompression dracoCompression) { var dracoGeoInfo = new DracoGeometryInfo(); string fileName = Path.GetTempFileName(); try { dracoCompression.Write(fileName); byte[] dracoBytes = GetDracoBytes(fileName); WriteDracoBytes(dracoBytes, out dracoGeoInfo.bufferIndex, out dracoGeoInfo.byteOffset); dracoGeoInfo.byteLength = dracoBytes.Length; var geo = DracoCompression.DecompressFile(fileName); if (geo.ObjectType == ObjectType.Mesh) { var mesh = (Rhino.Geometry.Mesh)geo; Point2f point2f; Point3f point3f; Vector3f vector3f; // Vertices Stats dracoGeoInfo.verticesNum = mesh.Vertices.Count; point3f = mesh.Vertices.Min(); dracoGeoInfo.verticesMin = new float[] { point3f.X, point3f.Y, point3f.Z }; point3f = mesh.Vertices.Max(); dracoGeoInfo.verticesMax = new float[] { point3f.X, point3f.Y, point3f.Z }; // Triangle Stats dracoGeoInfo.trianglesNum = mesh.Faces.TriangleCount; dracoGeoInfo.trianglesMin = 0; dracoGeoInfo.trianglesMax = dracoGeoInfo.verticesNum - 1; // Normals Stats dracoGeoInfo.normalsNum = mesh.Normals.Count; vector3f = mesh.Normals.Min(); dracoGeoInfo.normalsMin = new float[] { vector3f.X, vector3f.Y, vector3f.Z }; vector3f = mesh.Normals.Max(); dracoGeoInfo.normalsMax = new float[] { vector3f.X, vector3f.Y, vector3f.Z }; // TexCoord Stats dracoGeoInfo.texCoordsNum = mesh.TextureCoordinates.Count; if (dracoGeoInfo.texCoordsNum > 0) { point2f = mesh.TextureCoordinates.Min(); dracoGeoInfo.texCoordsMin = new float[] { point2f.X, point2f.Y }; point2f = mesh.TextureCoordinates.Max(); dracoGeoInfo.texCoordsMax = new float[] { point2f.X, point2f.Y }; } dracoGeoInfo.success = true; } geo.Dispose(); dracoCompression.Dispose(); } finally { File.Delete(fileName); } return(dracoGeoInfo); }
private void AddRhinoObjectDraco(ObjectExportData data) { var materialIndex = GetMaterial(data.RenderMaterial, data.Object); var primitives = new List <MeshPrimitive>(); // For each rhino mesh, create gl-buffers, gl-meshes, etc. foreach (var rhinoMesh in data.Meshes) { if (options.MapRhinoZToGltfY) { rhinoMesh.Transform(ZtoYUp); } rhinoMesh.TextureCoordinates.ReverseTextureCoordinates(1); var dracoComp = DracoCompression.Compress( rhinoMesh, new DracoCompressionOptions() { CompressionLevel = options.DracoCompressionLevel, IncludeNormals = true, IncludeTextureCoordinates = true, IncludeVertexColors = false, PositionQuantizationBits = options.DracoQuantizationBitsPosition, NormalQuantizationBits = options.DracoQuantizationBitsNormal, TextureCoordintateQuantizationBits = options.DracoQuantizationBitsTexture } ); DracoGeometryInfo dracoGeoInfo = AddDracoGeometry(dracoComp); var compMeshBufferView = new BufferView() { Buffer = dracoGeoInfo.bufferIndex, ByteOffset = dracoGeoInfo.byteOffset, ByteLength = dracoGeoInfo.byteLength, }; int compMeshBufferViewIdx = dummy.BufferViews.AddAndReturnIndex(compMeshBufferView); var vtxAccessor = new Accessor { Type = Accessor.TypeEnum.VEC3, ComponentType = Accessor.ComponentTypeEnum.FLOAT, Count = dracoGeoInfo.verticesNum, Min = dracoGeoInfo.verticesMin, Max = dracoGeoInfo.verticesMax, ByteOffset = 0, }; int vtxAccessorIdx = dummy.Accessors.AddAndReturnIndex(vtxAccessor); // // Accessor Triangles Vertex IDs var idsAccessor = new Accessor { Type = Accessor.TypeEnum.SCALAR, ComponentType = Accessor.ComponentTypeEnum.UNSIGNED_INT, Count = dracoGeoInfo.trianglesNum, Min = new float[] { dracoGeoInfo.trianglesMin }, Max = new float[] { dracoGeoInfo.trianglesMax }, ByteOffset = 0, }; int idsAccessorIdx = dummy.Accessors.AddAndReturnIndex(idsAccessor); // Accessor Normals var normalsAccessor = new Accessor { Type = Accessor.TypeEnum.VEC3, ComponentType = Accessor.ComponentTypeEnum.FLOAT, Count = dracoGeoInfo.normalsNum, Min = dracoGeoInfo.normalsMin, Max = dracoGeoInfo.normalsMax, ByteOffset = 0, }; int normalsAccessorIdx = dummy.Accessors.AddAndReturnIndex(normalsAccessor); var primitive = new MeshPrimitive() { Attributes = new Dictionary <string, int>() { { Constants.PositionAttributeTag, vtxAccessorIdx }, { Constants.NormalAttributeTag, normalsAccessorIdx }, }, Indices = idsAccessorIdx, Material = materialIndex, }; if (dracoGeoInfo.texCoordsNum > 0) { // Accessor TexCoords var texCoordsAccessor = new Accessor { Type = Accessor.TypeEnum.VEC2, ComponentType = Accessor.ComponentTypeEnum.FLOAT, Count = dracoGeoInfo.texCoordsNum, Min = dracoGeoInfo.texCoordsMin, Max = dracoGeoInfo.texCoordsMax, ByteOffset = 0, }; int texCoordsAccessorIdx = dummy.Accessors.AddAndReturnIndex(texCoordsAccessor); primitive.Attributes.Add(Constants.TexCoord0AttributeTag, texCoordsAccessorIdx); primitive.Extensions = new Dictionary <string, object>() { { Constants.DracoMeshCompressionExtensionTag, new { bufferView = compMeshBufferViewIdx, attributes = new { POSITION = 0, NORMAL = 1, TEXCOORD_0 = 2 } } } }; } else { primitive.Extensions = new Dictionary <string, object>() { { Constants.DracoMeshCompressionExtensionTag, new { bufferView = compMeshBufferViewIdx, attributes = new { POSITION = 0, NORMAL = 1, } } } }; } // Create mesh primitives.Add(primitive); } var mesh = new glTFLoader.Schema.Mesh() { Primitives = primitives.ToArray(), }; int meshIndex = dummy.Meshes.AddAndReturnIndex(mesh); var node = new Node() { Mesh = meshIndex, }; int nodeIndex = dummy.Nodes.AddAndReturnIndex(node); dummy.Scenes[dummy.Scene].Nodes.Add(nodeIndex); }