static ElementId ToHost(Rhino.DocObjects.Material mat, Document doc, Dictionary <string, Autodesk.Revit.DB.Material> materials) { var id = ElementId.InvalidElementId; if (mat.HasName) { var matName = mat.Name; if (materials.TryGetValue(matName, out var material)) { id = material.Id; } else { id = Autodesk.Revit.DB.Material.Create(doc, matName); var newMaterial = doc.GetElement(id) as Autodesk.Revit.DB.Material; newMaterial.Color = mat.PreviewColor.ToHost(); newMaterial.Shininess = (int)Math.Round(mat.Shine / Rhino.DocObjects.Material.MaxShine * 128.0); newMaterial.Smoothness = (int)Math.Round(mat.Reflectivity * 100.0); newMaterial.Transparency = (int)Math.Round(mat.Transparency * 100.0); newMaterial.AppearanceAssetId = ToHost(mat.RenderMaterial, doc, matName); materials.Add(matName, newMaterial); } } return(id); }
private static ProbableMaterial WhatMaterial(RenderMaterial rm, Rhino.DocObjects.Material m) { if (rm.TypeId.Equals(RenderMaterial.PictureMaterialGuid)) { return(ProbableMaterial.Picture); } if (rm.TypeId.Equals(RenderMaterial.PlasterMaterialGuid)) { return(ProbableMaterial.Plaster); } if (rm.TypeId.Equals(RenderMaterial.GlassMaterialGuid)) { return(ProbableMaterial.Glass); } if (rm.TypeId.Equals(RenderMaterial.GemMaterialGuid)) { return(ProbableMaterial.Gem); } if (rm.TypeId.Equals(RenderMaterial.PaintMaterialGuid)) { return(ProbableMaterial.Paint); } if (rm.TypeId.Equals(RenderMaterial.PlasticMaterialGuid)) { return(ProbableMaterial.Plastic); } if (rm.TypeId.Equals(RenderMaterial.MetalMaterialGuid)) { return(ProbableMaterial.Metal); } if (rm.SmellsLikePlaster || rm.SmellsLikeTexturedPlaster) { return(ProbableMaterial.Plaster); } if (rm.SmellsLikeGlass || rm.SmellsLikeTexturedGlass) { return(ProbableMaterial.Glass); } if (rm.SmellsLikeGem || rm.SmellsLikeTexturedGem) { return(ProbableMaterial.Gem); } if (rm.SmellsLikePaint || rm.SmellsLikeTexturedPaint) { return(ProbableMaterial.Paint); } if (rm.SmellsLikePlastic || rm.SmellsLikeTexturedPlastic) { return(ProbableMaterial.Plastic); } if (rm.SmellsLikeMetal || rm.SmellsLikeTexturedMetal) { return(ProbableMaterial.Metal); } return(ProbableMaterial.Custom); }
void HandleBaseColor(Rhino.DocObjects.Material rhinoMaterial, glTFLoader.Schema.Material gltfMaterial) { Rhino.DocObjects.Texture baseColorDoc = rhinoMaterial.GetTexture(TextureType.PBR_BaseColor); Rhino.DocObjects.Texture alphaTextureDoc = rhinoMaterial.GetTexture(TextureType.PBR_Alpha); RenderTexture baseColorTexture = rhinoMaterial.RenderMaterial.GetTextureFromUsage(RenderMaterial.StandardChildSlots.PbrBaseColor); RenderTexture alphaTexture = rhinoMaterial.RenderMaterial.GetTextureFromUsage(RenderMaterial.StandardChildSlots.PbrAlpha); bool baseColorLinear = baseColorTexture == null ? false : IsLinear(baseColorTexture); bool hasBaseColorTexture = baseColorDoc == null ? false : baseColorDoc.Enabled; bool hasAlphaTexture = alphaTextureDoc == null ? false : alphaTextureDoc.Enabled; bool baseColorDiffuseAlphaForTransparency = rhinoMaterial.PhysicallyBased.UseBaseColorTextureAlphaForObjectAlphaTransparencyTexture; Color4f baseColor = rhinoMaterial.PhysicallyBased.BaseColor; if (workflow.PreProcessColors) { baseColor = Color4f.ApplyGamma(baseColor, workflow.PreProcessGamma); } if (!hasBaseColorTexture && !hasAlphaTexture) { gltfMaterial.PbrMetallicRoughness.BaseColorFactor = new float[] { baseColor.R, baseColor.G, baseColor.B, (float)rhinoMaterial.PhysicallyBased.Alpha, }; if (rhinoMaterial.PhysicallyBased.Alpha == 1.0) { gltfMaterial.AlphaMode = glTFLoader.Schema.Material.AlphaModeEnum.OPAQUE; } else { gltfMaterial.AlphaMode = glTFLoader.Schema.Material.AlphaModeEnum.BLEND; } } else { gltfMaterial.PbrMetallicRoughness.BaseColorTexture = CombineBaseColorAndAlphaTexture(baseColorTexture, alphaTexture, baseColorDiffuseAlphaForTransparency, baseColor, baseColorLinear, (float)rhinoMaterial.PhysicallyBased.Alpha, out bool hasAlpha); if (hasAlpha) { gltfMaterial.AlphaMode = glTFLoader.Schema.Material.AlphaModeEnum.BLEND; } else { gltfMaterial.AlphaMode = glTFLoader.Schema.Material.AlphaModeEnum.OPAQUE; } } }
int GetMaterial(Rhino.DocObjects.Material material, Guid materialId) { if (!materialsMap.TryGetValue(materialId, out int materialIndex)) { RhinoMaterialGltfConverter materialConverter = new RhinoMaterialGltfConverter(options, dummy, binaryBuffer, material, workflow); materialIndex = materialConverter.AddMaterial(); materialsMap.Add(materialId, materialIndex); } return(materialIndex); }
static ElementId ToHost(Rhino.DocObjects.Material mat, Document doc, Dictionary <string, Autodesk.Revit.DB.Material> materials) { var id = ElementId.InvalidElementId; if (materials.TryGetValue(mat.Name ?? "Default", out var material)) { id = material.Id; } else { id = Autodesk.Revit.DB.Material.Create(doc, mat.Name); var newMaterial = doc.GetElement(id) as Autodesk.Revit.DB.Material; newMaterial.Color = new Autodesk.Revit.DB.Color(255, 255, 255); #if REVIT_2019 if (newMaterial.AppearanceAssetId == ElementId.InvalidElementId) { if (AppearanceAssetElement.GetAppearanceAssetElementByName(doc, mat.Name) is AppearanceAssetElement appearanceAssetElement) { newMaterial.AppearanceAssetId = appearanceAssetElement.Id; } else { appearanceAssetElement = AppearanceAssetElement.GetAppearanceAssetElementByName(doc, "Generic"); if (appearanceAssetElement is null) { var assets = Revit.ActiveUIApplication.Application.GetAssets(AssetType.Appearance); foreach (var asset in assets) { if (asset.Name == "Generic") { appearanceAssetElement = AppearanceAssetElement.Create(doc, mat.Name, asset); newMaterial.AppearanceAssetId = appearanceAssetElement.Id; break; } } } else { appearanceAssetElement = appearanceAssetElement.Duplicate(mat.Name); newMaterial.AppearanceAssetId = appearanceAssetElement.Id; } if (newMaterial.AppearanceAssetId != ElementId.InvalidElementId) { using (var editScope = new AppearanceAssetEditScope(doc)) { var editableAsset = editScope.Start(newMaterial.AppearanceAssetId); var genericDiffuseProperty = editableAsset.FindByName("generic_diffuse") as AssetPropertyDoubleArray4d; genericDiffuseProperty.SetValueAsColor(mat.DiffuseColor.ToHost()); var properties = new List <AssetProperty>(editableAsset.Size); for (int i = 0; i < editableAsset.Size; i++) { properties.Add(editableAsset[i]); } editScope.Commit(false); } } } } #endif materials.Add(mat.Name, newMaterial); } return(id); }
public static Rhino.Commands.Result AddTexture(Rhino.RhinoDoc doc) { // Select object to add texture const ObjectType filter = Rhino.DocObjects.ObjectType.Surface | Rhino.DocObjects.ObjectType.PolysrfFilter | Rhino.DocObjects.ObjectType.Mesh; Rhino.DocObjects.ObjRef objref; Rhino.Commands.Result rc = Rhino.Input.RhinoGet.GetOneObject("Select object to add texture", false, filter, out objref); if (rc != Rhino.Commands.Result.Success) { return(rc); } Rhino.DocObjects.RhinoObject rhino_object = objref.Object(); if (rhino_object == null) { return(Rhino.Commands.Result.Failure); } // Select texture Rhino.UI.OpenFileDialog fd = new Rhino.UI.OpenFileDialog(); fd.Filter = "Image Files (*.bmp;*.png;*.jpg)|*.bmp;*.png;*.jpg"; if (fd.ShowDialog() != System.Windows.Forms.DialogResult.OK) { return(Rhino.Commands.Result.Cancel); } // Verify texture string bitmap_filename = fd.FileName; if (string.IsNullOrEmpty(bitmap_filename) || !System.IO.File.Exists(bitmap_filename)) { return(Rhino.Commands.Result.Nothing); } // Make sure the object has it's material source set to "material_from_object" rhino_object.Attributes.MaterialSource = Rhino.DocObjects.ObjectMaterialSource.MaterialFromObject; // Make sure the object has a material assigned int material_index = rhino_object.Attributes.MaterialIndex; if (material_index < 0) { // Create a new material based on Rhino's default material material_index = doc.Materials.Add(); // Assign the new material (index) to the object. rhino_object.Attributes.MaterialIndex = material_index; } if (material_index >= 0) { Rhino.DocObjects.Material mat = doc.Materials[material_index]; mat.SetBumpTexture(bitmap_filename); mat.CommitChanges(); //Don't forget to update the object, if necessary rhino_object.CommitChanges(); doc.Views.Redraw(); return(Rhino.Commands.Result.Success); } return(Rhino.Commands.Result.Failure); }
protected override Result RunCommand(RhinoDoc doc, RunMode mode) { double tolerance = doc.ModelAbsoluteTolerance; List <Curve> icur = new List <Curve>(); GetObject gcr = new Rhino.Input.Custom.GetObject(); gcr.SetCommandPrompt("Select reference circles for stones. (No curves)"); gcr.GeometryFilter = Rhino.DocObjects.ObjectType.Curve; gcr.GroupSelect = true; gcr.SubObjectSelect = true; gcr.DeselectAllBeforePostSelect = true; gcr.OneByOnePostSelect = false; gcr.GetMultiple(1, 0); for (int ie = 0; ie < gcr.ObjectCount; ie++) { Rhino.DocObjects.ObjRef objref = gcr.Object(ie); Rhino.DocObjects.RhinoObject obj = objref.Object(); if (obj == null) { return(Result.Failure); } Curve refcr = objref.Curve(); if (refcr == null) { return(Result.Failure); } obj.Select(false); icur.Add(refcr); } var rm = FindMaterial(doc, "Diamond"); if (null == rm) { //Didn't find the material - create one and carry on. //Create a basic material var custom = new Rhino.DocObjects.Material(); custom.Reflectivity = 1; custom.Transparency = 0.2; custom.SetEnvironmentTexture(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "/Free Jewels Rhino Plug-Ins/Dia3.jpg"); custom.Name = "Diamond"; custom.CommitChanges(); rm = RenderMaterial.CreateBasicMaterial(custom); var docMats = doc.RenderMaterials; //docMats.BeginChange(RenderContent.ChangeContexts.Program); docMats.Add(rm); //docMats.EndChange(); } // Create Stone Mesh Rhino.Geometry.Mesh mesh = new Rhino.Geometry.Mesh(); mesh.Vertices.Add(0.0, 0.0, -0.44); //0 mesh.Vertices.Add(0.0, 0.097, -0.363); //1 mesh.Vertices.Add(0.069, 0.069, -0.363); //2 mesh.Vertices.Add(0.097, 0.0, -0.363); //3 mesh.Vertices.Add(0.0, 0.5, -0.013); //4 mesh.Vertices.Add(0.098, 0.49, -0.005); //5 mesh.Vertices.Add(0.191, 0.462, -0.013); //6 mesh.Vertices.Add(0.278, 0.416, -0.005); //7 mesh.Vertices.Add(0.354, 0.354, -0.013); //8 mesh.Vertices.Add(0.416, 0.278, -0.005); //9 mesh.Vertices.Add(0.462, 0.191, -0.013); //10 mesh.Vertices.Add(0.49, 0.098, -0.005); //11 mesh.Vertices.Add(0.5, 0.0, -0.013); //12 mesh.Vertices.Add(0.0, 0.5, 0.013); //13 mesh.Vertices.Add(0.098, 0.49, 0.005); //14 mesh.Vertices.Add(0.191, 0.462, 0.013); //15 mesh.Vertices.Add(0.278, 0.416, 0.005); //16 mesh.Vertices.Add(0.354, 0.354, 0.013); //17 mesh.Vertices.Add(0.416, 0.278, 0.005); //18 mesh.Vertices.Add(0.462, 0.191, 0.013); //19 mesh.Vertices.Add(0.49, 0.098, 0.005); //20 mesh.Vertices.Add(0.5, 0.0, 0.013); //21 mesh.Vertices.Add(0.0, 0.372, 0.12); //22 mesh.Vertices.Add(0.263, 0.263, 0.12); //23 mesh.Vertices.Add(0.372, 0.0, 0.12); //24 mesh.Vertices.Add(0.263, -0.263, 0.12); //25 mesh.Vertices.Add(0.0, -0.372, 0.12); //26 mesh.Vertices.Add(-0.263, -0.263, 0.12); //27 mesh.Vertices.Add(-0.372, 0.0, 0.12); //28 mesh.Vertices.Add(-0.263, 0.263, 0.12); //29 mesh.Vertices.Add(0.109, 0.263, 0.16); //30 mesh.Vertices.Add(0.263, 0.109, 0.16); //31 mesh.Vertices.Add(0.263, -0.109, 0.16); //32 mesh.Vertices.Add(0.109, -0.263, 0.16); //33 mesh.Vertices.Add(-0.109, -0.263, 0.16); //34 mesh.Vertices.Add(-0.263, -0.109, 0.16); //35 mesh.Vertices.Add(-0.263, 0.109, 0.16); //36 mesh.Vertices.Add(-0.109, 0.263, 0.16); //37 mesh.Vertices.Add(0.0, 0.0, 0.16); //38 mesh.Faces.AddFace(0, 1, 6, 2); mesh.Faces.AddFace(0, 2, 10, 3); mesh.Faces.AddFace(1, 4, 5, 6); mesh.Faces.AddFace(2, 6, 7, 8); mesh.Faces.AddFace(2, 8, 9, 10); mesh.Faces.AddFace(3, 10, 11, 12); mesh.Faces.AddFace(4, 13, 14, 5); mesh.Faces.AddFace(5, 14, 15, 6); mesh.Faces.AddFace(6, 15, 16, 7); mesh.Faces.AddFace(7, 16, 17, 8); mesh.Faces.AddFace(8, 17, 18, 9); mesh.Faces.AddFace(9, 18, 19, 10); mesh.Faces.AddFace(10, 19, 20, 11); mesh.Faces.AddFace(11, 20, 21, 12); mesh.Faces.AddFace(13, 22, 15, 14); mesh.Faces.AddFace(15, 23, 17, 16); mesh.Faces.AddFace(17, 23, 19, 18); mesh.Faces.AddFace(19, 24, 21, 20); mesh.Faces.AddFace(15, 22, 30, 23); mesh.Faces.AddFace(19, 23, 31, 24); mesh.Faces.AddFace(23, 30, 31); mesh.Faces.AddFace(24, 31, 32); mesh.Faces.AddFace(32, 31, 30, 38); mesh.Unweld(0.001, false); Mesh meshAll = new Mesh(); for (int i = 0; i < 4; i++) { meshAll.Append(mesh); Point3d center = new Point3d(0.0, 0.0, 0.0); Vector3d rotVec = new Vector3d(0.0, 0.0, 1.0); mesh.Rotate(Math.PI / 2, rotVec, center); } meshAll.Compact(); meshAll.Weld(0.001); //Get object Guid to apply render material var meshGuid = doc.Objects.AddMesh(meshAll); ObjRef objre = new ObjRef(meshGuid); RhinoObject obje = objre.Object(); obje.RenderMaterial = rm; obje.CommitChanges(); //Make InstanceDefinition string instDefCount = DateTime.Now.ToString("ddMMyyyyHHmmss"); var geometry = new System.Collections.Generic.List <Rhino.Geometry.GeometryBase>() { obje.Geometry }; var attributes = new System.Collections.Generic.List <Rhino.DocObjects.ObjectAttributes>() { obje.Attributes }; var stoneIndex = doc.InstanceDefinitions.Add("Stone" + instDefCount, "StoneMesh 1mm", Point3d.Origin, geometry, attributes); List <InstanceReferenceGeometry> meshPave = new List <InstanceReferenceGeometry>(); foreach (Curve c in icur) { Circle circle1 = new Circle(); c.TryGetCircle(out circle1, tolerance); double radius = circle1.Diameter; Point3d center = circle1.Center; Vector3d moveV = new Vector3d(center); Vector3d zaxis = new Vector3d(0.0, 0.0, 1.0); Plane planeOr = new Plane(center, zaxis); Plane planeNew = circle1.Plane; var transform1 = Transform.Translation(moveV); var transform2 = Transform.Scale(center, radius); var transform3 = Transform.PlaneToPlane(planeOr, planeNew); var stoneA = doc.Objects.AddInstanceObject(stoneIndex, transform1); var stoneB = doc.Objects.Transform(stoneA, transform2, true); var stoneC = doc.Objects.Transform(stoneB, transform3, true); ids.Add(stoneC); } doc.Groups.Add(ids); doc.Objects.Delete(obje); doc.Views.Redraw(); return(Result.Success); }
protected override Result RunCommand(RhinoDoc doc, RunMode mode) { int currIntOption = 0; var gi = new GetOption(); gi.SetCommandPrompt("Material Index"); gi.AcceptNumber(true, true); var resgi = gi.Get(); if (resgi == GetResult.Number) { currIntOption = Convert.ToInt32(gi.Number()); } Rhino.Input.Custom.GetObject go = new Rhino.Input.Custom.GetObject(); go.SetCommandPrompt("Select objects to apply material"); go.GroupSelect = true; go.SubObjectSelect = false; go.EnableClearObjectsOnEntry(false); go.EnableUnselectObjectsOnExit(false); go.DeselectAllBeforePostSelect = false; go.GetMultiple(1, 0); //Nothing to do - get out quick. if (go.ObjectCount == 0) { return(Result.Success); } var rm = FindMaterial(doc, matName[currIntOption]); if (null == rm) { //Didn't find the material - create one and carry on. //Create a basic material var custom = new Rhino.DocObjects.Material(); custom.Name = matName[currIntOption]; if (currIntOption == 13) { custom.SetEnvironmentTexture(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "/Free Jewels Rhino Plug-Ins/Dia3.jpg"); } custom.CommitChanges(); rm = RenderMaterial.CreateBasicMaterial(custom); rm.BeginChange(RenderContent.ChangeContexts.Program); rm.SetParameter("diffuse", System.Drawing.Color.Black); rm.SetParameter("reflectivity", 1.0); rm.SetParameter("reflectivity-color", System.Drawing.Color.FromArgb(r[currIntOption], g[currIntOption], b[currIntOption])); rm.SetParameter("transparency", fjMatTrans[currIntOption]); rm.SetParameter("shine", fjMatShine[currIntOption]); rm.SetParameter("polish-amount", fjMatShine[currIntOption]); rm.EndChange(); var docMats = doc.RenderMaterials; docMats.Add(rm); } //Now we always have a material to assign, this part is easy for (int i = 0; i < go.ObjectCount; i++) { var obj = go.Object(i).Object(); obj.RenderMaterial = rm; obj.CommitChanges(); } doc.Views.Redraw(); return(Result.Success); }
public static void Load(string filename, RhinoDoc doc) { var model = Interface.LoadModel(filename); if (model != null) { // dictionary with deserialized buffer data var bufferData = new Dictionary <int, byte[]>(); // accessorData contains a dictionary to the buffer data meant to be accessed by an accessor via a bufferView var accessorData = new Dictionary <int, dynamic>(); // material data contains a dictionary with the material index and the Rhino material ID var materialData = new Dictionary <int, int>(); // mesh data var meshData = new Dictionary <int, List <Rhino.Geometry.Mesh> >(); var nodeXformData = new Dictionary <int, Transform>(); var dir = Path.GetDirectoryName(filename); #region Read Buffers for (int i = 0; i < model.Buffers.Length; i++) { var data = Interface.LoadBinaryBuffer(model, i, filename); bufferData.Add(i, data); } #endregion #region Process Images //go through images in model //save them to disk if necessary const string EMBEDDEDPNG = "data:image/png;base64,"; const string EMBEDDEDJPEG = "data:image/jpeg;base64,"; var imageData = new Dictionary <int, string>(); //image index, image path if (model.Images != null) { for (int i = 0; i < model.Images.Length; i++) { var image = model.Images[i]; var name = image.Name ?? "embeddedImage_" + i; var extension = string.Empty; var imageStream = Stream.Null; if (image.BufferView.HasValue) { imageStream = Interface.OpenImageFile(model, i, filename); if (image.MimeType.HasValue) { if (image.MimeType == glTFLoader.Schema.Image.MimeTypeEnum.image_jpeg) { extension = ".jpg"; } else if (image.MimeType == glTFLoader.Schema.Image.MimeTypeEnum.image_png) { extension = ".png"; } } var imgPath = Path.Combine(dir, "EmbeddedImages"); if (!Directory.Exists(imgPath)) { Directory.CreateDirectory(imgPath); } imgPath = Path.Combine(imgPath, name + extension); using (var fileStream = File.Create(imgPath)) { imageStream.Seek(0, SeekOrigin.Begin); imageStream.CopyTo(fileStream); imageData.Add(i, imgPath); } } if (image.Uri != null && image.Uri.StartsWith("data:image/")) { if (image.Uri.StartsWith(EMBEDDEDPNG)) { extension = ".png"; } if (image.Uri.StartsWith(EMBEDDEDJPEG)) { extension = ".jpg"; } imageStream = Interface.OpenImageFile(model, i, filename); var imgPath = Path.Combine(dir, "EmbeddedImages"); if (!Directory.Exists(imgPath)) { Directory.CreateDirectory(imgPath); } imgPath = Path.Combine(imgPath, name + extension); using (var fileStream = File.Create(imgPath)) { imageStream.Seek(0, SeekOrigin.Begin); imageStream.CopyTo(fileStream); imageData.Add(i, imgPath); } } if (image.Uri != null && File.Exists(Path.Combine(dir, image.Uri))) { imageData.Add(i, Path.Combine(dir, image.Uri)); } } } #endregion #region Process Materials // TODO: Update for Rhino 7 PBR Materials if (model.Materials != null) { for (int i = 0; i < model.Materials.Length; i++) { var mat = model.Materials[i]; var rhinoMat = new Rhino.DocObjects.Material(); var texId = -1; int?sourceId = null; if (mat.NormalTexture != null) { } if (mat.OcclusionTexture != null) { } if (mat.EmissiveTexture != null) { } if (mat.PbrMetallicRoughness.BaseColorTexture != null) { texId = mat.PbrMetallicRoughness.BaseColorTexture.Index; sourceId = model.Textures[texId].Source.Value; rhinoMat.SetBitmapTexture(imageData[sourceId.Value]); } if (mat.PbrMetallicRoughness.MetallicRoughnessTexture != null) { texId = mat.PbrMetallicRoughness.MetallicRoughnessTexture.Index; sourceId = model.Textures[texId].Source.Value; rhinoMat.SetBumpTexture(imageData[sourceId.Value]); } rhinoMat.Name = mat.Name; var id = doc.Materials.Add(rhinoMat); var rMat = Rhino.Render.RenderMaterial.CreateBasicMaterial(rhinoMat, doc); doc.RenderMaterials.Add(rMat); materialData.Add(i, id); } } #endregion #region Access Buffers for (int i = 0; i < model.Accessors.Length; i++) { var accessor = model.Accessors[i]; //process, afterwards, check if sparse if (accessor.BufferView != null) { var bufferView = model.BufferViews[accessor.BufferView.Value]; var buffer = bufferData[bufferView.Buffer]; //byte[] //calculate byte length var elementBytes = GetTypeMultiplier(accessor.Type) * GetComponentTypeMultiplier(accessor.ComponentType); var stride = bufferView.ByteStride != null ? bufferView.ByteStride.Value : 0; var strideDiff = stride > 0 ? stride - elementBytes : 0; var count = (elementBytes + strideDiff) * accessor.Count; var arr = new byte[count]; System.Buffer.BlockCopy(buffer, bufferView.ByteOffset + accessor.ByteOffset, arr, 0, count); var res = AccessBuffer(accessor.Type, accessor.Count, accessor.ComponentType, stride, arr); accessorData.Add(i, res); } // if accessor is sparse, need to modify the data. accessorData index is i if (accessor.Sparse != null) { //TODO //If a BufferView is specified in the accessor, sparse acts a a way to replace values //if a BufferView does not exist in the accessor, just process the sparse data //access construct data var bufferViewI = model.BufferViews[accessor.Sparse.Indices.BufferView]; var bufferI = bufferData[bufferViewI.Buffer]; //byte[] var sparseComponentType = (Accessor.ComponentTypeEnum)accessor.Sparse.Indices.ComponentType; //calculate count var elementBytesI = GetTypeMultiplier(Accessor.TypeEnum.SCALAR) * GetComponentTypeMultiplier(sparseComponentType); var strideI = bufferViewI.ByteStride != null ? bufferViewI.ByteStride.Value : 0; var strideDiffI = strideI > 0 ? strideI - elementBytesI : 0; var countI = (elementBytesI + strideDiffI) * accessor.Sparse.Count; var arrI = new byte[countI]; System.Buffer.BlockCopy(bufferI, accessor.Sparse.Indices.ByteOffset + bufferViewI.ByteOffset, arrI, 0, countI); var resIndices = AccessBuffer(Accessor.TypeEnum.SCALAR, accessor.Sparse.Count, sparseComponentType, strideI, arrI); ///////// var bufferViewV = model.BufferViews[accessor.Sparse.Values.BufferView]; var bufferV = bufferData[bufferViewV.Buffer]; //byte[] //calculate count var elementBytesV = GetTypeMultiplier(accessor.Type) * GetComponentTypeMultiplier(accessor.ComponentType); var strideV = bufferViewV.ByteStride != null ? bufferViewV.ByteStride.Value : 0; var strideDiffV = strideV > 0 ? strideV - elementBytesV : 0; var countV = (elementBytesV + strideDiffV) * accessor.Sparse.Count; var arrV = new byte[countV]; System.Buffer.BlockCopy(bufferV, accessor.Sparse.Values.ByteOffset + bufferViewV.ByteOffset, arrV, 0, countV); var resValues = AccessBuffer(accessor.Type, accessor.Sparse.Count, accessor.ComponentType, strideV, arrV); //mod accessorData var valueCnt = 0; for (int j = 0; j < accessor.Sparse.Count; j++) { var index = resIndices[j]; var mult = GetTypeMultiplier(accessor.Type); var indexAccessorData = index * mult; for (int k = 0; k < mult; k++) { accessorData[i][indexAccessorData + k] = resValues[valueCnt]; valueCnt++; } } } } #endregion #region Process Meshes //foreach (var m in model.Meshes) for (int j = 0; j < model.Meshes.Length; j++) { var m = model.Meshes[j]; var groupId = doc.Groups.Add(m.Name); var meshes = new List <Rhino.Geometry.Mesh>(); foreach (var mp in m.Primitives) { //Do I need to treat different MeshPrimitive.ModeEnum differently? Yes because if we get POINTS, LINES, LINE_LOOP, LINE_STRIP then it won't be a mesh var meshPart = new Rhino.Geometry.Mesh(); foreach (var att in mp.Attributes) { var attributeData = accessorData[att.Value]; switch (att.Key) { case "POSITION": var pts = new List <Point3d>(); for (int i = 0; i <= attributeData.Count - 3; i = i + 3) { pts.Add(new Point3d(attributeData[i], attributeData[i + 1], attributeData[i + 2])); } meshPart.Vertices.AddVertices(pts); break; case "TEXCOORD_0": var uvs = new List <Point2f>(); for (int i = 0; i <= attributeData.Count - 2; i = i + 2) { uvs.Add(new Point2f(attributeData[i], attributeData[i + 1])); } meshPart.TextureCoordinates.AddRange(uvs.ToArray()); break; case "NORMAL": var normals = new List <Vector3f>(); for (int i = 0; i <= attributeData.Count - 3; i = i + 3) { normals.Add(new Vector3f(attributeData[i], attributeData[i + 1], attributeData[i + 2])); } meshPart.Normals.AddRange(normals.ToArray()); break; case "COLOR_0": var colors = new List <Color>(); for (int i = 0; i <= attributeData.Count - 3; i = i + 3) { colors.Add(ColorFromSingle(attributeData[i], attributeData[i + 1], attributeData[i + 2])); } meshPart.VertexColors.AppendColors(colors.ToArray()); break; default: RhinoApp.WriteLine("Rhino glTF Importer: Attribute {0} not supported in Rhino. Skipping.", att.Key); /* NOT SUPPORTED IN RHINO ... yet * * - TANGENT * - TEXCOORD_1 //might be supported with multiple mapping channels? * - JOINTS_0 * - WEIGHTS_0 * */ break; } } if (mp.Indices != null) { // Indices can be defined as UNSIGNED_BYTE 5121 or UNSIGNED_SHORT 5123, maybe even as UNSIGNED_INT 5125 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((int)faceIds[i], (int)faceIds[i + 1], (int)faceIds[i + 2])); } meshPart.Faces.AddFaces(faces); } //meshPart.Weld(Math.PI); // TODO: CLEANUP var oa = new ObjectAttributes { MaterialSource = ObjectMaterialSource.MaterialFromObject, MaterialIndex = (mp.Material != null) ? materialData[mp.Material.Value] : 0, Name = m.Name }; //if (mp.Material != null) //oa.MaterialIndex = materialData[mp.Material.Value]; meshPart.Compact(); #if DEBUG if (!meshPart.IsValid) { //meshPart.Weld(Math.PI); //meshPart.Vertices.Align(0.0001); //meshPart.Vertices.CombineIdentical(true, true); //meshPart.Vertices.CullUnused(); //meshPart.FaceNormals.ComputeFaceNormals(); //meshPart.Normals.ComputeNormals(); if (!meshPart.IsValid) { for (int i = 0; i < meshPart.Vertices.Count; i++) { doc.Objects.AddTextDot(i.ToString(), meshPart.Vertices[i]); var ptD = new Point3d(meshPart.Vertices[i]); ptD.Transform(Transform.Translation(meshPart.Normals[i])); doc.Objects.AddLine(meshPart.Vertices[i], ptD); } foreach (var mf in meshPart.Faces) { RhinoApp.WriteLine("Rhino glTF: Mesh Face - {0}", mf); } doc.Objects.AddPoints(meshPart.Vertices.ToPoint3dArray()); } else { doc.Objects.AddMesh(meshPart, oa); } } #endif // var guid = doc.Objects.AddMesh(meshPart, oa); // doc.Groups.AddToGroup(groupId, guid); meshes.Add(meshPart); } meshData.Add(j, meshes); } #endregion #region Process Nodes Transforms for (int i = 0; i < model.Nodes.Length; i++) { nodeXformData.Add(i, ProcessNode(model.Nodes[i])); } //for (int i = 0; i < model.Nodes.Length; i++) //TraverseNode(model, model.Nodes[i], Transform.Unset, meshData); TraverseNode(model, model.Nodes[model.Scenes[model.Scene.Value].Nodes[0]], Transform.Identity, meshData); #endregion #region Add to doc for (int i = 0; i < model.Nodes.Length; i++) { var n = model.Nodes[i]; if (n.Mesh.HasValue) { int j = 0; foreach (var meshes in meshData.Values) { var group = doc.Groups.Add(n.Name); foreach (var m in meshes) { // TODO: Assign material var oa = new ObjectAttributes { Name = model.Meshes[j].Name }; var guid = doc.Objects.AddMesh(m, oa); doc.Groups.AddToGroup(group, guid); } j++; } } } #endregion } }
public glTFLoader.Schema.TextureInfo AddMetallicRoughnessTexture(Rhino.DocObjects.Material rhinoMaterial) { Rhino.DocObjects.Texture metalTexture = rhinoMaterial.PhysicallyBased.GetTexture(TextureType.PBR_Metallic); Rhino.DocObjects.Texture roughnessTexture = rhinoMaterial.PhysicallyBased.GetTexture(TextureType.PBR_Roughness); bool hasMetalTexture = metalTexture == null ? false : metalTexture.Enabled; bool hasRoughnessTexture = roughnessTexture == null ? false : roughnessTexture.Enabled; RenderTexture renderTextureMetal = null; RenderTexture renderTextureRoughness = null; int mWidth = 0; int mHeight = 0; int rWidth = 0; int rHeight = 0; // Get the textures if (hasMetalTexture) { renderTextureMetal = rhinoMaterial.RenderMaterial.GetTextureFromUsage(Rhino.Render.RenderMaterial.StandardChildSlots.PbrMetallic); renderTextureMetal.PixelSize(out mWidth, out mHeight, out int _w0); } if (hasRoughnessTexture) { renderTextureRoughness = rhinoMaterial.RenderMaterial.GetTextureFromUsage(RenderMaterial.StandardChildSlots.PbrRoughness); renderTextureRoughness.PixelSize(out rWidth, out rHeight, out int _w1); } int width = Math.Max(mWidth, rWidth); int height = Math.Max(mHeight, rHeight); TextureEvaluator evalMetal = null; TextureEvaluator evalRoughness = null; // Metal if (hasMetalTexture) { evalMetal = renderTextureMetal.CreateEvaluator(RenderTexture.TextureEvaluatorFlags.Normal); } // Roughness if (hasRoughnessTexture) { evalRoughness = renderTextureRoughness.CreateEvaluator(RenderTexture.TextureEvaluatorFlags.Normal); } // Copy Metal to the blue channel, roughness to the green var bitmap = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb); float metallic = (float)rhinoMaterial.PhysicallyBased.Metallic; float roughness = (float)rhinoMaterial.PhysicallyBased.Roughness; for (var j = 0; j < height - 1; j += 1) { for (var i = 0; i < width - 1; i += 1) { double x = (double)i / (double)(width - 1); double y = (double)j / (double)(height - 1); Point3d uvw = new Point3d(x, y, 0.0); float g = 0; float b = 0; if (hasMetalTexture) { Color4f metal = evalMetal.GetColor(uvw, Vector3d.Zero, Vector3d.Zero); b = metal.L; //grayscale maps, so we want lumonosity } else { b = metallic; } if (hasRoughnessTexture) { Color4f roughnessColor = evalRoughness.GetColor(uvw, Vector3d.ZAxis, Vector3d.Zero); g = roughnessColor.L; //grayscale maps, so we want lumonosity } else { g = roughness; } Color4f color = new Color4f(0.0f, g, b, 1.0f); bitmap.SetPixel(i, height - j - 1, color.AsSystemColor()); } } return(GetTextureInfoFromBitmap(bitmap)); }
public RhinoMaterialGltfConverter(glTFExportOptions options, gltfSchemaDummy dummy, List <byte> binaryBuffer, Rhino.DocObjects.Material rhinoMaterial, LinearWorkflow workflow) { this.options = options; this.dummy = dummy; this.binaryBuffer = binaryBuffer; this.rhinoMaterial = rhinoMaterial; this.workflow = workflow; }
/// <summary> /// This is the method that actually does the work. /// </summary> /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param> protected override void SolveInstance(IGH_DataAccess DA) { /* * Original Version Written by Giulio Piacentino - 2010 11 21 - for Grasshopper 0.8.002 * Enhanced by Co-de-iT (Alessio) - now bakes on chosen layer(s) and in groups */ GeometryBase obj = null; if (!DA.GetData(0, ref obj)) { return; } string name = ""; DA.GetData(1, ref name); string layer = ""; DA.GetData(2, ref layer); Color color = new Color(); DA.GetData(3, ref color); Object material = new Object(); DA.GetData(4, ref material); int group_n = 0; DA.GetData(5, ref group_n); bool group = false; DA.GetData(6, ref group); bool bake_iT = false; DA.GetData(7, ref bake_iT); if (!bake_iT) { return; } //Make new attribute to set name Rhino.DocObjects.ObjectAttributes att = new Rhino.DocObjects.ObjectAttributes(); //Set object name if (!string.IsNullOrEmpty(name)) { att.Name = name; } //Set color if (!color.IsEmpty) { att.ColorSource = Rhino.DocObjects.ObjectColorSource.ColorFromObject; //Make the color type "by object" att.ObjectColor = color; att.PlotColorSource = Rhino.DocObjects.ObjectPlotColorSource.PlotColorFromObject; //Make the plot color type "by object" att.PlotColor = color; } // Set group if (group) { Rhino.RhinoDoc.ActiveDoc.Groups.Add(Convert.ToString(group_n)); att.AddToGroup(group_n); } //Set layer if (!string.IsNullOrEmpty(layer) && Rhino.DocObjects.Layer.IsValidName(layer)) { //Get the current layer index Rhino.DocObjects.Tables.LayerTable layerTable = Rhino.RhinoDoc.ActiveDoc.Layers; //int layerIndex = layerTable.Find(layer, true); int layerIndex = layerTable.FindByFullPath(layer, -1); if (layerIndex < 0) //This layer does not exist, we add it { Rhino.DocObjects.Layer onlayer = new Rhino.DocObjects.Layer(); //Make a new layer onlayer.Name = layer; onlayer.Color = Color.Gainsboro; // sets new layer color - future dev: choose new layers color layerIndex = layerTable.Add(onlayer); //Add the layer to the layer table if (layerIndex > -1) //We managed to add the layer! { att.LayerIndex = layerIndex; //Print("Added new layer to the document at position " + layerIndex + " named " + layer + ". "); } //else //Print("Layer did not add. Try cleaning up your layers."); //This never happened to me. } else { att.LayerIndex = layerIndex; //We simply add to the existing layer } } //Set plotweight //if (pWidth > 0) //{ // att.PlotWeightSource = Rhino.DocObjects.ObjectPlotWeightSource.PlotWeightFromObject; // att.PlotWeight = pWidth; //} //Set material bool materialByName = !string.IsNullOrEmpty(material as string); Rhino.Display.DisplayMaterial inMaterial; if (material is GH_Material) { GH_Material gMat = material as GH_Material; inMaterial = gMat.Value as Rhino.Display.DisplayMaterial; } else { inMaterial = material as Rhino.Display.DisplayMaterial; } if (material is Color) { inMaterial = new Rhino.Display.DisplayMaterial((Color)material); } if (material != null && inMaterial == null && !materialByName) { if (!(material is string)) { try //We also resort to try with IConvertible { inMaterial = (Rhino.Display.DisplayMaterial)Convert.ChangeType(material, typeof(Rhino.Display.DisplayMaterial)); } catch (InvalidCastException) { } } } if (inMaterial != null || materialByName) { string matName; if (!materialByName) { matName = string.Format("D:{0}-E:{1}-S:{2},{3}-T:{4}", Format(inMaterial.Diffuse), Format(inMaterial.Emission), Format(inMaterial.Specular), inMaterial.Shine.ToString(), inMaterial.Transparency.ToString() ); } else { matName = (string)material; } int materialIndex = Rhino.RhinoDoc.ActiveDoc.Materials.Find(matName, true); if (materialIndex < 0 && !materialByName) //Material does not exist and we have its specs { materialIndex = Rhino.RhinoDoc.ActiveDoc.Materials.Add(); //Let's add it if (materialIndex > -1) { //Print("Added new material at position " + materialIndex + " named \"" + matName + "\". "); Rhino.DocObjects.Material m = Rhino.RhinoDoc.ActiveDoc.Materials[materialIndex]; m.Name = matName; m.DiffuseColor = inMaterial.Diffuse; m.EmissionColor = inMaterial.Emission; //m.ReflectionColor = inMaterial.Specular; m.SpecularColor = inMaterial.Specular; m.Shine = inMaterial.Shine; m.Transparency = inMaterial.Transparency; //m.TransparentColor = no equivalent m.CommitChanges(); att.MaterialSource = Rhino.DocObjects.ObjectMaterialSource.MaterialFromObject; att.MaterialIndex = materialIndex; } else { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Material did not add. Try cleaning up your materials."); //This never happened to me. } } else if (materialIndex < 0 && materialByName) //Material does not exist and we do not have its specs. We do nothing { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Warning: material name not found. I cannot set the source to this material name. Add a material with name: " + matName); } else { //If this material exists, we do not replace it! att.MaterialSource = Rhino.DocObjects.ObjectMaterialSource.MaterialFromObject; att.MaterialIndex = materialIndex; } } //Set wire density //if (wires == -1 || wires > 0) //{ // att.WireDensity = wires; //} //Bake to the right type of object switch (obj.ObjectType) { case Rhino.DocObjects.ObjectType.Brep: Rhino.RhinoDoc.ActiveDoc.Objects.AddBrep(obj as Brep, att); break; case Rhino.DocObjects.ObjectType.Curve: Rhino.RhinoDoc.ActiveDoc.Objects.AddCurve(obj as Curve, att); break; case Rhino.DocObjects.ObjectType.Point: Rhino.RhinoDoc.ActiveDoc.Objects.AddPoint((obj as Rhino.Geometry.Point).Location, att); break; case Rhino.DocObjects.ObjectType.Surface: Rhino.RhinoDoc.ActiveDoc.Objects.AddSurface(obj as Surface, att); break; case Rhino.DocObjects.ObjectType.Mesh: Rhino.RhinoDoc.ActiveDoc.Objects.AddMesh(obj as Mesh, att); break; case Rhino.DocObjects.ObjectType.Extrusion: typeof(Rhino.DocObjects.Tables.ObjectTable).InvokeMember("AddExtrusion", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.InvokeMethod, null, Rhino.RhinoDoc.ActiveDoc.Objects, new object[] { obj, att }); break; case Rhino.DocObjects.ObjectType.PointSet: Rhino.RhinoDoc.ActiveDoc.Objects.AddPointCloud(obj as Rhino.Geometry.PointCloud, att); //This is a speculative entry break; default: AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "The script does not know how to handle this type of geometry: " + obj.GetType().FullName); break; } }
private void AddRhinoObjectText(Rhino.Geometry.Mesh[] rhinoMeshes, Rhino.DocObjects.Material material, Guid materialId, RhinoObject rhinoObject) { int materialIndex = GetMaterial(material, materialId); var primitives = new List <MeshPrimitive>(); foreach (var rhinoMesh in rhinoMeshes) { if (options.MapRhinoZToGltfY) { rhinoMesh.Transform(ZtoYUp); } rhinoMesh.TextureCoordinates.ReverseTextureCoordinates(1); rhinoMesh.Faces.ConvertQuadsToTriangles(); var vtxBuffer = CreateVerticesBuffer(rhinoMesh.Vertices, out Point3d vtxMin, out Point3d vtxMax); int vtxBufferIdx = dummy.Buffers.AddAndReturnIndex(vtxBuffer); var idsBuffer = CreateIndicesBuffer(rhinoMesh.Faces, out int indicesCount); int idsBufferIdx = dummy.Buffers.AddAndReturnIndex(idsBuffer); var normalsBuffer = CreateNormalsBuffer(rhinoMesh.Normals, out Vector3f normalsMin, out Vector3f normalsMax); int normalsBufferIdx = dummy.Buffers.AddAndReturnIndex(normalsBuffer); var texCoordsBuffer = CreateTextureCoordinatesBuffer(rhinoMesh.TextureCoordinates, out Point2f texCoordsMin, out Point2f texCoordsMax); int texCoordsBufferIdx = dummy.Buffers.AddAndReturnIndex(texCoordsBuffer); var vtxBufferView = new BufferView() { Buffer = vtxBufferIdx, ByteOffset = 0, ByteLength = vtxBuffer.ByteLength, Target = BufferView.TargetEnum.ARRAY_BUFFER, }; int vtxBufferViewIdx = dummy.BufferViews.AddAndReturnIndex(vtxBufferView); var idsBufferView = new BufferView() { Buffer = idsBufferIdx, ByteOffset = 0, ByteLength = idsBuffer.ByteLength, Target = BufferView.TargetEnum.ELEMENT_ARRAY_BUFFER, }; int idsBufferViewIdx = dummy.BufferViews.AddAndReturnIndex(idsBufferView); BufferView normalsBufferView = new BufferView() { Buffer = normalsBufferIdx, ByteOffset = 0, ByteLength = normalsBuffer.ByteLength, Target = BufferView.TargetEnum.ARRAY_BUFFER, }; int normalsBufferViewIdx = dummy.BufferViews.AddAndReturnIndex(normalsBufferView); BufferView texCoordsBufferView = new BufferView() { Buffer = texCoordsBufferIdx, ByteOffset = 0, ByteLength = texCoordsBuffer.ByteLength, Target = BufferView.TargetEnum.ARRAY_BUFFER, }; int texCoordsBufferViewIdx = dummy.BufferViews.AddAndReturnIndex(texCoordsBufferView); // Create accessors Accessor vtxAccessor = new Accessor() { BufferView = vtxBufferViewIdx, Count = rhinoMesh.Vertices.Count, Min = new float[] { (float)vtxMin.X, (float)vtxMin.Y, (float)vtxMin.Z }, Max = new float[] { (float)vtxMax.X, (float)vtxMax.Y, (float)vtxMax.Z }, Type = Accessor.TypeEnum.VEC3, ComponentType = Accessor.ComponentTypeEnum.FLOAT, ByteOffset = 0, }; int vtxAccessorIdx = dummy.Accessors.AddAndReturnIndex(vtxAccessor); Accessor idsAccessor = new Accessor() { BufferView = idsBufferViewIdx, Count = indicesCount, Min = new float[] { 0 }, Max = new float[] { rhinoMesh.Vertices.Count - 1 }, Type = Accessor.TypeEnum.SCALAR, ComponentType = Accessor.ComponentTypeEnum.UNSIGNED_INT, ByteOffset = 0, }; int idsAccessorIdx = dummy.Accessors.AddAndReturnIndex(idsAccessor); Accessor normalsAccessor = new Accessor() { BufferView = normalsBufferViewIdx, Count = rhinoMesh.Normals.Count, Min = new float[] { normalsMin.X, normalsMin.Y, normalsMin.Z }, Max = new float[] { normalsMax.X, normalsMax.Y, normalsMax.Z }, Type = Accessor.TypeEnum.VEC3, ComponentType = Accessor.ComponentTypeEnum.FLOAT, ByteOffset = 0, }; int normalsAccessorIdx = dummy.Accessors.AddAndReturnIndex(normalsAccessor); Accessor texCoordsAccessor = new Accessor() { BufferView = texCoordsBufferViewIdx, Count = rhinoMesh.TextureCoordinates.Count, Min = new float[] { texCoordsMin.X, texCoordsMin.Y }, Max = new float[] { texCoordsMax.X, texCoordsMax.Y }, Type = Accessor.TypeEnum.VEC2, ComponentType = Accessor.ComponentTypeEnum.FLOAT, ByteOffset = 0, }; int texCoordsAccessorIdx = dummy.Accessors.AddAndReturnIndex(texCoordsAccessor); var primitive = new MeshPrimitive() { Attributes = new Dictionary <string, int>() { { Constants.PositionAttributeTag, vtxAccessorIdx }, { Constants.NormalAttributeTag, normalsAccessorIdx }, { Constants.TexCoord0AttributeTag, texCoordsAccessorIdx }, }, Indices = idsAccessorIdx, Material = materialIndex, }; // Create mesh primitives.Add(primitive); } var mesh = new glTFLoader.Schema.Mesh() { Primitives = primitives.ToArray(), }; int idxMesh = dummy.Meshes.AddAndReturnIndex(mesh); var node = new Node() { Mesh = idxMesh, Name = string.IsNullOrEmpty(rhinoObject.Name) ? null : rhinoObject.Name, }; int idxNode = dummy.Nodes.AddAndReturnIndex(node); dummy.Scenes[dummy.Scene].Nodes.Add(idxNode); }
private void AddRhinoObjectDraco(Rhino.Geometry.Mesh[] rhinoMeshes, Rhino.DocObjects.Material material, Guid materialId, RhinoObject rhinoObject) { int materialIndex = GetMaterial(material, materialId); var primitives = new List <MeshPrimitive>(); // For each rhino mesh, create gl-buffers, gl-meshes, etc. foreach (var rhinoMesh in rhinoMeshes) { 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); // 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); var primitive = new MeshPrimitive() { Attributes = new Dictionary <string, int>() { { Constants.PositionAttributeTag, vtxAccessorIdx }, { Constants.NormalAttributeTag, normalsAccessorIdx }, { Constants.TexCoord0AttributeTag, texCoordsAccessorIdx }, }, Indices = idsAccessorIdx, Material = materialIndex, Extensions = new Dictionary <string, object>() { { Constants.DracoMeshCompressionExtensionTag, new { bufferView = compMeshBufferViewIdx, attributes = new { POSITION = 0, NORMAL = 1, TEXCOORD_0 = 2 } } } } }; // 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); }