From 143d2676979ff0381a66506dce68b5912cbc2a88 Mon Sep 17 00:00:00 2001 From: Peter Krattenmacher Date: Wed, 18 Aug 2021 12:30:11 +0200 Subject: [PATCH 01/19] Initial texture mapping support. --- glTF-BinExporter/RhinoDocGltfConverter.cs | 24 ++++++++++++++++ .../RhinoMaterialGltfConverter.cs | 28 +++++++++---------- glTF-BinExporter/RhinoMeshGltfConverter.cs | 27 ++++++++++++++++++ 3 files changed, 65 insertions(+), 14 deletions(-) diff --git a/glTF-BinExporter/RhinoDocGltfConverter.cs b/glTF-BinExporter/RhinoDocGltfConverter.cs index 8503902..da5105d 100644 --- a/glTF-BinExporter/RhinoDocGltfConverter.cs +++ b/glTF-BinExporter/RhinoDocGltfConverter.cs @@ -15,6 +15,7 @@ public struct ObjectExportData { public Rhino.Geometry.Mesh[] Meshes; public RenderMaterial[] RenderMaterials; + public TextureMapping[] TextureMappings; public RhinoObject Object; } @@ -307,6 +308,8 @@ public List SanitizeRhinoObjects(IEnumerable rhin if (isValidGeometry && rhinoObject.ObjectType != ObjectType.InstanceReference) { + TextureMapping[] textureMappings = GetTextureMappings(rhinoObject); + var meshes = GetMeshes(rhinoObject); if (meshes.Length > 0) //Objects need a mesh to export @@ -315,6 +318,7 @@ public List SanitizeRhinoObjects(IEnumerable rhin { Meshes = meshes, RenderMaterials = mats, + TextureMappings = textureMappings, Object = rhinoObject, }); } @@ -331,6 +335,8 @@ public List SanitizeRhinoObjects(IEnumerable rhin // Transform the exploded geo into its correct place foreach (var item in objects.Zip(transforms, (rObj, trans) => (rhinoObject: rObj, trans))) { + var textureMappings = GetTextureMappings(item.rhinoObject); + var meshes = GetMeshes(item.rhinoObject); foreach (var mesh in meshes) @@ -344,6 +350,7 @@ public List SanitizeRhinoObjects(IEnumerable rhin { Meshes = meshes, RenderMaterials = mats, + TextureMappings = textureMappings, Object = item.rhinoObject, }); } @@ -358,6 +365,23 @@ public List SanitizeRhinoObjects(IEnumerable rhin return rhinoObjectsRes; } + private TextureMapping[] GetTextureMappings(RhinoObject rhinoObject) + { + var textureMappingIndeces = rhinoObject.GetTextureChannels(); + Array.Sort(textureMappingIndeces); + var textureMappings = new TextureMapping[textureMappingIndeces.Max()+1]; + int j = 0; + for (int i = 0; i < textureMappings.Length; i++) + { + if (textureMappingIndeces[j] == i) + { + textureMappings[i] = rhinoObject.GetTextureMapping(textureMappingIndeces[j]); + j++; + } + } + return textureMappings; + } + private void ExplodeRecursive(InstanceObject instanceObject, Rhino.Geometry.Transform instanceTransform, List pieces, List transforms) { for (int i = 0; i < instanceObject.InstanceDefinition.ObjectCount; i++) diff --git a/glTF-BinExporter/RhinoMaterialGltfConverter.cs b/glTF-BinExporter/RhinoMaterialGltfConverter.cs index 1a47338..447a27c 100644 --- a/glTF-BinExporter/RhinoMaterialGltfConverter.cs +++ b/glTF-BinExporter/RhinoMaterialGltfConverter.cs @@ -83,12 +83,12 @@ public int AddMaterial() if (occlusionTexture != null && occlusionTexture.Enabled) { - material.OcclusionTexture = AddTextureOcclusion(occlusionTexture.FileReference.FullPath); + material.OcclusionTexture = AddTextureOcclusion(occlusionTexture.FileReference.FullPath, occlusionTexture.MappingChannelId); } if (emissiveTexture != null && emissiveTexture.Enabled) { - material.EmissiveTexture = AddTexture(emissiveTexture.FileReference.FullPath); + material.EmissiveTexture = AddTexture(emissiveTexture.FileReference.FullPath, emissiveTexture.MappingChannelId); float emissionMultiplier = 1.0f; @@ -142,7 +142,7 @@ public int AddMaterial() if(clearcoatTexture != null && clearcoatTexture.Enabled) { - clearcoat.ClearcoatTexture = AddTexture(clearcoatTexture.FileReference.FullPath); + clearcoat.ClearcoatTexture = AddTexture(clearcoatTexture.FileReference.FullPath, clearcoatTexture.MappingChannelId); clearcoat.ClearcoatFactor = 1.0f; } else @@ -152,7 +152,7 @@ public int AddMaterial() if(clearcoatRoughessTexture != null && clearcoatRoughessTexture.Enabled) { - clearcoat.ClearcoatRoughnessTexture = AddTexture(clearcoatRoughessTexture.FileReference.FullPath); + clearcoat.ClearcoatRoughnessTexture = AddTexture(clearcoatRoughessTexture.FileReference.FullPath, clearcoatRoughessTexture.MappingChannelId); clearcoat.ClearcoatRoughnessFactor = 1.0f; } else @@ -201,7 +201,7 @@ glTFLoader.Schema.TextureInfo CreateOpacityTexture(Rhino.DocObjects.Texture text glTFLoader.Schema.TextureInfo textureInfo = new glTFLoader.Schema.TextureInfo() { Index = textureIndex, - TexCoord = 0, + TexCoord = texture.MappingChannelId, }; return textureInfo; @@ -376,7 +376,7 @@ glTFLoader.Schema.TextureInfo CombineBaseColorAndAlphaTexture(RenderTexture base //Testing //bitmap.Save(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "out.png")); - return GetTextureInfoFromBitmap(bitmap); + return GetTextureInfoFromBitmap(bitmap, baseColorTexture == null?(alphaTexture == null? 0:alphaTexture.GetMappingChannel()):baseColorTexture.GetMappingChannel()); } private int AddTextureToBuffers(string texturePath) @@ -461,11 +461,11 @@ private byte[] GetImageBytesFromFile(string fileName) return GetImageBytes(bmp); } - private glTFLoader.Schema.TextureInfo AddTexture(string texturePath) + private glTFLoader.Schema.TextureInfo AddTexture(string texturePath, int mappingChannel) { int textureIdx = AddTextureToBuffers(texturePath); - return new glTFLoader.Schema.TextureInfo() { Index = textureIdx, TexCoord = 0 }; + return new glTFLoader.Schema.TextureInfo() { Index = textureIdx, TexCoord = mappingChannel }; } private glTFLoader.Schema.MaterialNormalTextureInfo AddTextureNormal(Rhino.DocObjects.Texture normalTexture) @@ -477,7 +477,7 @@ private glTFLoader.Schema.MaterialNormalTextureInfo AddTextureNormal(Rhino.DocOb return new glTFLoader.Schema.MaterialNormalTextureInfo() { Index = textureIdx, - TexCoord = 0, + TexCoord = normalTexture.MappingChannelId, Scale = (float)constant, }; } @@ -494,14 +494,14 @@ private int AddNormalTexture(Rhino.DocObjects.Texture normalTexture) return GetTextureFromBitmap(bmp); } - private glTFLoader.Schema.MaterialOcclusionTextureInfo AddTextureOcclusion(string texturePath) + private glTFLoader.Schema.MaterialOcclusionTextureInfo AddTextureOcclusion(string texturePath, int mappingChannel) { int textureIdx = AddTextureToBuffers(texturePath); return new glTFLoader.Schema.MaterialOcclusionTextureInfo() { Index = textureIdx, - TexCoord = 0, + TexCoord = mappingChannel, Strength = 0.9f }; } @@ -595,7 +595,7 @@ public glTFLoader.Schema.TextureInfo AddMetallicRoughnessTexture(Rhino.DocObject } } - return GetTextureInfoFromBitmap(bitmap); + return GetTextureInfoFromBitmap(bitmap, renderTextureMetal == null? (renderTextureRoughness == null? 0 : renderTextureRoughness.GetMappingChannel()) : renderTextureMetal.GetMappingChannel()); } private int GetTextureFromBitmap(Bitmap bitmap) @@ -613,14 +613,14 @@ private int GetTextureFromBitmap(Bitmap bitmap) return dummy.Textures.AddAndReturnIndex(texture); } - private glTFLoader.Schema.TextureInfo GetTextureInfoFromBitmap(Bitmap bitmap) + private glTFLoader.Schema.TextureInfo GetTextureInfoFromBitmap(Bitmap bitmap, int mappingChannel) { int textureIdx = GetTextureFromBitmap(bitmap); return new glTFLoader.Schema.TextureInfo() { Index = textureIdx, - TexCoord = 0 + TexCoord = mappingChannel }; } diff --git a/glTF-BinExporter/RhinoMeshGltfConverter.cs b/glTF-BinExporter/RhinoMeshGltfConverter.cs index c009fc8..6725efd 100644 --- a/glTF-BinExporter/RhinoMeshGltfConverter.cs +++ b/glTF-BinExporter/RhinoMeshGltfConverter.cs @@ -85,6 +85,7 @@ private void PreprocessMesh(Mesh rhinoMesh) { if (exportData.Meshes[i] == null) continue; var rhinoMesh = exportData.Meshes[i]; + var textureMappings = exportData.TextureMappings; PreprocessMesh(rhinoMesh); @@ -100,6 +101,16 @@ private void PreprocessMesh(Mesh rhinoMesh) bool exportTextureCoordinates = ExportTextureCoordinates(rhinoMesh); bool exportVertexColors = ExportVertexColors(rhinoMesh); + if(exportTextureCoordinates) + { + Transform transform = Transform.Identity; + foreach (var textureMapping in textureMappings) + { + if (textureMapping == null) continue; + rhinoMesh.SetCachedTextureCoordinates(textureMapping, ref transform); + } + } + glTFLoader.Schema.MeshPrimitive primitive = new glTFLoader.Schema.MeshPrimitive() { Attributes = new Dictionary(), @@ -125,6 +136,17 @@ private void PreprocessMesh(Mesh rhinoMesh) int textureCoordinatesAccessorIdx = GetTextureCoordinatesAccessor(rhinoMesh.TextureCoordinates); primitive.Attributes.Add(Constants.TexCoord0AttributeTag, textureCoordinatesAccessorIdx); + + for (int j = 1; j < textureMappings.Length; j++) + { + if(textureMappings[j] == null) primitive.Attributes.Add("TEXCOORD_" + j, textureCoordinatesAccessorIdx); + else + { + rhinoMesh.SetTextureCoordinates(textureMappings[j], Transform.Identity, false); + int newTextureCoordinatesAccessorIdx = GetTextureCoordinatesAccessor(rhinoMesh.TextureCoordinates); + primitive.Attributes.Add("TEXCOORD_" + j, newTextureCoordinatesAccessorIdx); + } + } } if (exportVertexColors) @@ -150,6 +172,11 @@ private void PreprocessMesh(Mesh rhinoMesh) if(exportTextureCoordinates) { dracoCompressionObject.Attributes.Add(Constants.TexCoord0AttributeTag, currentGeometryInfo.TextureCoordinatesAttributePosition); + + for (int j = 1; j <= textureMappings.Length; j++) + { + dracoCompressionObject.Attributes.Add("TEXCOORD_" + j, currentGeometryInfo.TextureCoordinatesAttributePosition); + } } if(exportVertexColors) From 3bfecb8e056c4e37bf24e81202c293303d6977c4 Mon Sep 17 00:00:00 2001 From: Peter Krattenmacher Date: Wed, 18 Aug 2021 14:16:31 +0200 Subject: [PATCH 02/19] Fixes. --- glTF-BinExporter/RhinoDocGltfConverter.cs | 1 + glTF-BinExporter/RhinoMeshGltfConverter.cs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/glTF-BinExporter/RhinoDocGltfConverter.cs b/glTF-BinExporter/RhinoDocGltfConverter.cs index da5105d..35cb037 100644 --- a/glTF-BinExporter/RhinoDocGltfConverter.cs +++ b/glTF-BinExporter/RhinoDocGltfConverter.cs @@ -369,6 +369,7 @@ private TextureMapping[] GetTextureMappings(RhinoObject rhinoObject) { var textureMappingIndeces = rhinoObject.GetTextureChannels(); Array.Sort(textureMappingIndeces); + if (textureMappingIndeces.Length == 0) return new TextureMapping[0]; var textureMappings = new TextureMapping[textureMappingIndeces.Max()+1]; int j = 0; for (int i = 0; i < textureMappings.Length; i++) diff --git a/glTF-BinExporter/RhinoMeshGltfConverter.cs b/glTF-BinExporter/RhinoMeshGltfConverter.cs index 6725efd..b96c128 100644 --- a/glTF-BinExporter/RhinoMeshGltfConverter.cs +++ b/glTF-BinExporter/RhinoMeshGltfConverter.cs @@ -189,7 +189,7 @@ private void PreprocessMesh(Mesh rhinoMesh) primitive.Extensions.Add(Constants.DracoMeshCompressionExtensionTag, dracoCompressionObject); } - if(materialIndeces != null) primitive.Material = materialIndeces[i]; + if(materialIndeces.Length > 0) primitive.Material = materialIndeces[i]; primitives.Add(primitive); } From 485f19013f5c35191fceb905085954ebab729824 Mon Sep 17 00:00:00 2001 From: Peter Krattenmacher Date: Fri, 20 Aug 2021 12:15:08 +0200 Subject: [PATCH 03/19] Get object transform from rhinoObject.GetTextureMapping(...) method. --- glTF-BinExporter/RhinoDocGltfConverter.cs | 24 ++++++++++++++++------ glTF-BinExporter/RhinoMeshGltfConverter.cs | 2 +- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/glTF-BinExporter/RhinoDocGltfConverter.cs b/glTF-BinExporter/RhinoDocGltfConverter.cs index e6d446b..3471dbe 100644 --- a/glTF-BinExporter/RhinoDocGltfConverter.cs +++ b/glTF-BinExporter/RhinoDocGltfConverter.cs @@ -8,6 +8,7 @@ using glTFLoader.Schema; using Rhino.Render; using Rhino.Display; +using Rhino.Geometry; namespace glTF_BinExporter { @@ -15,7 +16,8 @@ public struct ObjectExportData { public Rhino.Geometry.Mesh[] Meshes; public RenderMaterial[] RenderMaterials; - public TextureMapping[] TextureMappings; + public TextureMapping[] TextureMappings; + public Transform ObjectTransform; public RhinoObject Object; } @@ -360,7 +362,8 @@ public List SanitizeRhinoObjects(IEnumerable rhin if (isValidGeometry && rhinoObject.ObjectType != ObjectType.InstanceReference) { - TextureMapping[] textureMappings = GetTextureMappings(rhinoObject); + Transform objectTransform; + TextureMapping[] textureMappings = GetTextureMappings(rhinoObject, out objectTransform); var meshes = GetMeshes(rhinoObject); @@ -371,6 +374,7 @@ public List SanitizeRhinoObjects(IEnumerable rhin Meshes = meshes, RenderMaterials = mats, TextureMappings = textureMappings, + ObjectTransform = objectTransform, Object = rhinoObject, }); } @@ -387,7 +391,8 @@ public List SanitizeRhinoObjects(IEnumerable rhin // Transform the exploded geo into its correct place foreach (var item in objects.Zip(transforms, (rObj, trans) => (rhinoObject: rObj, trans))) { - var textureMappings = GetTextureMappings(item.rhinoObject); + Transform objectTransform; + var textureMappings = GetTextureMappings(item.rhinoObject, out objectTransform); var meshes = GetMeshes(item.rhinoObject); @@ -403,6 +408,7 @@ public List SanitizeRhinoObjects(IEnumerable rhin Meshes = meshes, RenderMaterials = mats, TextureMappings = textureMappings, + ObjectTransform = objectTransform, Object = item.rhinoObject, }); } @@ -417,18 +423,24 @@ public List SanitizeRhinoObjects(IEnumerable rhin return rhinoObjectsRes; } - private TextureMapping[] GetTextureMappings(RhinoObject rhinoObject) + private TextureMapping[] GetTextureMappings(RhinoObject rhinoObject, out Transform objectTransform) { + objectTransform = Transform.Unset; + var textureMappingIndeces = rhinoObject.GetTextureChannels(); Array.Sort(textureMappingIndeces); - if (textureMappingIndeces.Length == 0) return new TextureMapping[0]; + if (textureMappingIndeces.Length == 0) + { + return new TextureMapping[0]; + } + var textureMappings = new TextureMapping[textureMappingIndeces.Max()+1]; int j = 0; for (int i = 0; i < textureMappings.Length; i++) { if (textureMappingIndeces[j] == i) { - textureMappings[i] = rhinoObject.GetTextureMapping(textureMappingIndeces[j]); + textureMappings[i] = rhinoObject.GetTextureMapping(textureMappingIndeces[j], out objectTransform); j++; } } diff --git a/glTF-BinExporter/RhinoMeshGltfConverter.cs b/glTF-BinExporter/RhinoMeshGltfConverter.cs index 7532534..d0e4c35 100644 --- a/glTF-BinExporter/RhinoMeshGltfConverter.cs +++ b/glTF-BinExporter/RhinoMeshGltfConverter.cs @@ -146,7 +146,7 @@ private void PreprocessMesh(Mesh rhinoMesh) if(textureMappings[j] == null) primitive.Attributes.Add("TEXCOORD_" + j, textureCoordinatesAccessorIdx); else { - rhinoMesh.SetTextureCoordinates(textureMappings[j], Transform.Identity, false); + rhinoMesh.SetTextureCoordinates(textureMappings[j], exportData.ObjectTransform, false); int newTextureCoordinatesAccessorIdx = GetTextureCoordinatesAccessor(rhinoMesh.TextureCoordinates); primitive.Attributes.Add("TEXCOORD_" + j, newTextureCoordinatesAccessorIdx); } From a6fb9cc649967f8bc29aaaa06ea11fcecbe6526c Mon Sep 17 00:00:00 2001 From: Peter Krattenmacher Date: Sat, 21 Aug 2021 13:54:40 +0200 Subject: [PATCH 04/19] Merge materials on layer or object level as well as the default material. --- glTF-BinExporter/RhinoDocGltfConverter.cs | 74 ++++++++++++++++------- 1 file changed, 53 insertions(+), 21 deletions(-) diff --git a/glTF-BinExporter/RhinoDocGltfConverter.cs b/glTF-BinExporter/RhinoDocGltfConverter.cs index 0ca9ab1..14e76e7 100644 --- a/glTF-BinExporter/RhinoDocGltfConverter.cs +++ b/glTF-BinExporter/RhinoDocGltfConverter.cs @@ -1,13 +1,11 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Rhino.DocObjects; +using glTFLoader.Schema; using Rhino; -using glTFLoader.Schema; -using Rhino.Render; using Rhino.Display; +using Rhino.DocObjects; +using Rhino.Render; +using System; +using System.Collections.Generic; +using System.Linq; namespace glTF_BinExporter { @@ -50,6 +48,8 @@ public RhinoDocGltfConverter(glTFExportOptions options, bool binary, RhinoDoc do private Dictionary layers = new Dictionary(); + private Dictionary layerMaterialIndices = new Dictionary(); + public Gltf ConvertToGltf() { dummy.Scene = 0; @@ -68,7 +68,7 @@ public Gltf ConvertToGltf() WrapT = Sampler.WrapTEnum.REPEAT, }); - if(options.UseDracoCompression) + if (options.UseDracoCompression) { dummy.ExtensionsUsed.Add(Constants.DracoMeshCompressionExtensionTag); dummy.ExtensionsRequired.Add(Constants.DracoMeshCompressionExtensionTag); @@ -79,7 +79,7 @@ public Gltf ConvertToGltf() var sanitized = SanitizeRhinoObjects(objects); - foreach(ObjectExportData exportData in sanitized) + foreach (ObjectExportData exportData in sanitized) { int[] materialIndices = GetMaterials(exportData.RenderMaterials, exportData.Object); @@ -94,7 +94,7 @@ public Gltf ConvertToGltf() int nodeIndex = dummy.Nodes.AddAndReturnIndex(node); - if(options.ExportLayers) + if (options.ExportLayers) { AddToLayer(RhinoDoc.ActiveDoc.Layers[exportData.Object.Attributes.LayerIndex], nodeIndex); } @@ -104,7 +104,7 @@ public Gltf ConvertToGltf() } } - if(binary && binaryBuffer.Count > 0) + if (binary && binaryBuffer.Count > 0) { //have to add the empty buffer for the binary file header dummy.Buffers.Add(new glTFLoader.Schema.Buffer() @@ -119,7 +119,7 @@ public Gltf ConvertToGltf() private void AddToLayer(Layer layer, int child) { - if(layers.TryGetValue(layer.Index, out Node node)) + if (layers.TryGetValue(layer.Index, out Node node)) { if (node.Children == null) { @@ -165,8 +165,11 @@ public byte[] GetBinaryBuffer() int[] GetMaterials(RenderMaterial[] materials, RhinoObject rhinoObject) { + RhinoObject[] subObjects = rhinoObject.GetSubObjects(); int[] materialIndices = new int[materials.Length]; + Dictionary colorIndices = new Dictionary(); + for (int i = 0; i < materials.Length; i++) { var material = materials[i]; @@ -176,18 +179,36 @@ int[] GetMaterials(RenderMaterial[] materials, RhinoObject rhinoObject) return null; } + Guid materialId; if (material == null && options.UseDisplayColorForUnsetMaterials) { - Color4f objectColor = GetObjectColor(rhinoObject); - materialIndices[i] = CreateSolidColorMaterial(objectColor, GetObjectName(rhinoObject)); + if (options.ExportLayers) + { + if (subObjects[i].Attributes.ColorSource == ObjectColorSource.ColorFromLayer) + { + materialIndices[i] = GetLayerMaterial(rhinoObject); + continue; + } + } + + Color4f objectColor = GetObjectColor(subObjects[i]); + if (!colorIndices.TryGetValue(objectColor, out int colorIndex)) + { + colorIndex = CreateSolidColorMaterial(objectColor, GetObjectName(rhinoObject)); + colorIndices.Add(objectColor, colorIndex); + } + materialIndices[i] = colorIndex; continue; } else if (material == null) { material = Rhino.DocObjects.Material.DefaultMaterial.RenderMaterial; + materialId = new Guid(); + } + else + { + materialId = material.Id; } - - Guid materialId = material.Id; if (!materialsMap.TryGetValue(materialId, out int materialIndex)) { @@ -202,6 +223,17 @@ int[] GetMaterials(RenderMaterial[] materials, RhinoObject rhinoObject) return materialIndices; } + private int GetLayerMaterial(RhinoObject rhinoObject) + { + if (!layerMaterialIndices.TryGetValue(rhinoObject.Attributes.LayerIndex, out int layerMaterialIndex)) + { + Color4f objectColor = GetObjectColor(rhinoObject); + layerMaterialIndex = CreateSolidColorMaterial(objectColor, RhinoDoc.ActiveDoc.Layers[rhinoObject.Attributes.LayerIndex].Name); + layerMaterialIndices.Add(rhinoObject.Attributes.LayerIndex, layerMaterialIndex); + } + return layerMaterialIndex; + } + int CreateSolidColorMaterial(Color4f color, string name) { glTFLoader.Schema.Material material = new glTFLoader.Schema.Material() @@ -218,11 +250,11 @@ int CreateSolidColorMaterial(Color4f color, string name) Color4f GetObjectColor(RhinoObject rhinoObject) { - if(rhinoObject.Attributes.ColorSource == ObjectColorSource.ColorFromLayer) + if (rhinoObject.Attributes.ColorSource == ObjectColorSource.ColorFromLayer) { int layerIndex = rhinoObject.Attributes.LayerIndex; - return new Color4f(rhinoObject.Document.Layers[layerIndex].Color); + return new Color4f(RhinoDoc.ActiveDoc.Layers[layerIndex].Color); } else { @@ -239,7 +271,7 @@ public Rhino.Geometry.Mesh[] GetMeshes(RhinoObject rhinoObject) return new Rhino.Geometry.Mesh[] { meshObj.MeshGeometry }; } - else if(rhinoObject.ObjectType == ObjectType.SubD) + else if (rhinoObject.ObjectType == ObjectType.SubD) { SubDObject subdObject = rhinoObject as SubDObject; @@ -303,7 +335,7 @@ public bool MeshIsValidForExport(Rhino.Geometry.Mesh mesh) return false; } - if(!options.ExportOpenMeshes && !mesh.IsClosed) + if (!options.ExportOpenMeshes && !mesh.IsClosed) { return false; } From f8f544dafcf60929c9e8002f8cf987551fc64df9 Mon Sep 17 00:00:00 2001 From: Peter Krattenmacher Date: Sat, 21 Aug 2021 15:39:22 +0200 Subject: [PATCH 05/19] Add texture coordinates options. --- glTF-BinExporter/Constants.cs | 1 + glTF-BinExporter/RhinoDocGltfConverter.cs | 32 +++++-- .../RhinoMaterialGltfConverter.cs | 26 ++++- glTF-BinExporter/RhinoMeshGltfConverter.cs | 56 +++++++++-- glTF-BinExporter/glTFBinExporterPlugin.cs | 27 ++++++ glTF-BinExporter/glTFExportOptions.cs | 4 + glTF-BinExporter/glTFExportOptionsDialog.cs | 96 +++++++++++++++++++ 7 files changed, 221 insertions(+), 21 deletions(-) diff --git a/glTF-BinExporter/Constants.cs b/glTF-BinExporter/Constants.cs index 02e8fbe..347839d 100644 --- a/glTF-BinExporter/Constants.cs +++ b/glTF-BinExporter/Constants.cs @@ -27,6 +27,7 @@ public static class Constants public const string PositionAttributeTag = "POSITION"; public const string NormalAttributeTag = "NORMAL"; public const string TexCoord0AttributeTag = "TEXCOORD_0"; + public const string TexCoord1AttributeTag = "TEXCOORD_1"; public const string VertexColorAttributeTag = "COLOR_0"; public const string DracoMeshCompressionExtensionTag = "KHR_draco_mesh_compression"; diff --git a/glTF-BinExporter/RhinoDocGltfConverter.cs b/glTF-BinExporter/RhinoDocGltfConverter.cs index 3471dbe..ae089c2 100644 --- a/glTF-BinExporter/RhinoDocGltfConverter.cs +++ b/glTF-BinExporter/RhinoDocGltfConverter.cs @@ -434,14 +434,34 @@ private TextureMapping[] GetTextureMappings(RhinoObject rhinoObject, out Transfo return new TextureMapping[0]; } - var textureMappings = new TextureMapping[textureMappingIndeces.Max()+1]; - int j = 0; - for (int i = 0; i < textureMappings.Length; i++) + TextureMapping[] textureMappings; + if (options.ExportAllTextureCoordinates) { - if (textureMappingIndeces[j] == i) + textureMappings = new TextureMapping[textureMappingIndeces.Max() + 1]; + int j = 0; + for (int i = 0; i < textureMappings.Length; i++) { - textureMappings[i] = rhinoObject.GetTextureMapping(textureMappingIndeces[j], out objectTransform); - j++; + if (textureMappingIndeces[j] == i) + { + textureMappings[i] = rhinoObject.GetTextureMapping(textureMappingIndeces[j], out objectTransform); + j++; + } + } + } + else + { + textureMappings = new TextureMapping[2]; + + if (textureMappingIndeces.Contains(options.UV0)) + { + textureMappings[0] = rhinoObject.GetTextureMapping(options.UV0, out objectTransform); + } + if (options.UV0 != options.UV1) + { + if (textureMappingIndeces.Contains(options.UV1)) + { + textureMappings[1] = rhinoObject.GetTextureMapping(options.UV1, out objectTransform); + } } } return textureMappings; diff --git a/glTF-BinExporter/RhinoMaterialGltfConverter.cs b/glTF-BinExporter/RhinoMaterialGltfConverter.cs index 8c0b707..7ec2d24 100644 --- a/glTF-BinExporter/RhinoMaterialGltfConverter.cs +++ b/glTF-BinExporter/RhinoMaterialGltfConverter.cs @@ -210,7 +210,7 @@ glTFLoader.Schema.TextureInfo CreateOpacityTexture(Rhino.DocObjects.Texture text glTFLoader.Schema.TextureInfo textureInfo = new glTFLoader.Schema.TextureInfo() { Index = textureIndex, - TexCoord = texture.MappingChannelId, + TexCoord = GetMappingChannel(texture.MappingChannelId), }; return textureInfo; @@ -474,7 +474,23 @@ private glTFLoader.Schema.TextureInfo AddTexture(string texturePath, int mapping { int textureIdx = AddTextureToBuffers(texturePath); - return new glTFLoader.Schema.TextureInfo() { Index = textureIdx, TexCoord = mappingChannel }; + return new glTFLoader.Schema.TextureInfo() { Index = textureIdx, TexCoord = GetMappingChannel(mappingChannel) }; + } + + private int GetMappingChannel(int mappingChannel) + { + if (options.ExportAllTextureCoordinates) return mappingChannel; + else + { + if (mappingChannel == options.UV0) return 0; + else if (mappingChannel == options.UV1) return 1; + else + { + if (options.UV0 == 0) return 0; + else if (options.UV1 == 0) return 0; + else return 0; + } + } } private glTFLoader.Schema.MaterialNormalTextureInfo AddTextureNormal(Rhino.DocObjects.Texture normalTexture) @@ -486,7 +502,7 @@ private glTFLoader.Schema.MaterialNormalTextureInfo AddTextureNormal(Rhino.DocOb return new glTFLoader.Schema.MaterialNormalTextureInfo() { Index = textureIdx, - TexCoord = normalTexture.MappingChannelId, + TexCoord = GetMappingChannel(normalTexture.MappingChannelId), Scale = (float)constant, }; } @@ -510,7 +526,7 @@ private glTFLoader.Schema.MaterialOcclusionTextureInfo AddTextureOcclusion(strin return new glTFLoader.Schema.MaterialOcclusionTextureInfo() { Index = textureIdx, - TexCoord = mappingChannel, + TexCoord = GetMappingChannel(mappingChannel), Strength = 0.9f }; } @@ -629,7 +645,7 @@ private glTFLoader.Schema.TextureInfo GetTextureInfoFromBitmap(Bitmap bitmap, in return new glTFLoader.Schema.TextureInfo() { Index = textureIdx, - TexCoord = mappingChannel + TexCoord = GetMappingChannel(mappingChannel) }; } diff --git a/glTF-BinExporter/RhinoMeshGltfConverter.cs b/glTF-BinExporter/RhinoMeshGltfConverter.cs index d0e4c35..aa6796c 100644 --- a/glTF-BinExporter/RhinoMeshGltfConverter.cs +++ b/glTF-BinExporter/RhinoMeshGltfConverter.cs @@ -107,11 +107,10 @@ private void PreprocessMesh(Mesh rhinoMesh) if(exportTextureCoordinates) { - Transform transform = Transform.Identity; foreach (var textureMapping in textureMappings) { if (textureMapping == null) continue; - rhinoMesh.SetCachedTextureCoordinates(textureMapping, ref transform); + rhinoMesh.SetCachedTextureCoordinates(textureMapping, ref exportData.ObjectTransform); } } @@ -137,20 +136,57 @@ private void PreprocessMesh(Mesh rhinoMesh) if (exportTextureCoordinates) { - int textureCoordinatesAccessorIdx = GetTextureCoordinatesAccessor(rhinoMesh.TextureCoordinates); - - primitive.Attributes.Add(Constants.TexCoord0AttributeTag, textureCoordinatesAccessorIdx); + if (options.ExportAllTextureCoordinates) + { + int textureCoordinatesAccessorIdx = GetTextureCoordinatesAccessor(rhinoMesh.TextureCoordinates); + primitive.Attributes.Add(Constants.TexCoord0AttributeTag, textureCoordinatesAccessorIdx); - for (int j = 1; j < textureMappings.Length; j++) + for (int j = 1; j < textureMappings.Length; j++) + { + if (textureMappings[j] == null) primitive.Attributes.Add("TEXCOORD_" + j, textureCoordinatesAccessorIdx); + else + { + rhinoMesh.SetTextureCoordinates(textureMappings[j], exportData.ObjectTransform, false); + int newTextureCoordinatesAccessorIdx = GetTextureCoordinatesAccessor(rhinoMesh.TextureCoordinates); + primitive.Attributes.Add("TEXCOORD_" + j, newTextureCoordinatesAccessorIdx); + } + } + } + else { - if(textureMappings[j] == null) primitive.Attributes.Add("TEXCOORD_" + j, textureCoordinatesAccessorIdx); + var defaultTextureCoordinates = rhinoMesh.TextureCoordinates; + int textureCoordinatesAccessorIdx = -1; + + if (textureMappings[0] == null) + { + textureCoordinatesAccessorIdx = GetTextureCoordinatesAccessor(defaultTextureCoordinates); + primitive.Attributes.Add(Constants.TexCoord0AttributeTag, textureCoordinatesAccessorIdx); + } else { - rhinoMesh.SetTextureCoordinates(textureMappings[j], exportData.ObjectTransform, false); + rhinoMesh.SetTextureCoordinates(textureMappings[0], exportData.ObjectTransform, false); int newTextureCoordinatesAccessorIdx = GetTextureCoordinatesAccessor(rhinoMesh.TextureCoordinates); - primitive.Attributes.Add("TEXCOORD_" + j, newTextureCoordinatesAccessorIdx); + primitive.Attributes.Add(Constants.TexCoord0AttributeTag, newTextureCoordinatesAccessorIdx); + } + if (textureMappings[1] == null && options.UV1 == 0 && options.UV0 != options.UV1) + { + if (textureCoordinatesAccessorIdx == -1) + { + textureCoordinatesAccessorIdx = GetTextureCoordinatesAccessor(defaultTextureCoordinates); + primitive.Attributes.Add(Constants.TexCoord1AttributeTag, textureCoordinatesAccessorIdx); + } + else + { + primitive.Attributes.Add(Constants.TexCoord1AttributeTag, textureCoordinatesAccessorIdx); + } } - } + else if(options.UV0 != options.UV1) + { + rhinoMesh.SetTextureCoordinates(textureMappings[1], exportData.ObjectTransform, false); + int newTextureCoordinatesAccessorIdx = GetTextureCoordinatesAccessor(rhinoMesh.TextureCoordinates); + primitive.Attributes.Add(Constants.TexCoord1AttributeTag, newTextureCoordinatesAccessorIdx); + } + } } if (exportVertexColors) diff --git a/glTF-BinExporter/glTFBinExporterPlugin.cs b/glTF-BinExporter/glTFBinExporterPlugin.cs index 20995fd..844d488 100644 --- a/glTF-BinExporter/glTFBinExporterPlugin.cs +++ b/glTF-BinExporter/glTFBinExporterPlugin.cs @@ -147,6 +147,33 @@ public static bool ExportTextureCoordinates set => Instance.Settings.SetBool(ExportTextureCoordinatesKey, value); } + private const string UV0Key = "UV0"; + public const int UV0Default = 0; + + public static int UV0 + { + get => Instance.Settings.GetInteger(UV0Key, UV0Default); + set => Instance.Settings.SetInteger(UV0Key, value); + } + + private const string UV1Key = "UV1"; + public const int UV1Default = 0; + + public static int UV1 + { + get => Instance.Settings.GetInteger(UV1Key, UV1Default); + set => Instance.Settings.SetInteger(UV1Key, value); + } + + public const string ExportAllTextureCoordinatesKey = "ExportAllTextureCoordinates"; + public const bool ExportAllTextureCoordinatesDefault = false; + + public static bool ExportAllTextureCoordinates + { + get => Instance.Settings.GetBool(ExportAllTextureCoordinatesKey, ExportAllTextureCoordinatesDefault); + set => Instance.Settings.SetBool(ExportAllTextureCoordinatesKey, value); + } + public const string ExportVertexNormalsKey = "ExportVertexNormals"; public const bool ExportVertexNormalsDefault = true; diff --git a/glTF-BinExporter/glTFExportOptions.cs b/glTF-BinExporter/glTFExportOptions.cs index 94b0f7c..7d4352a 100644 --- a/glTF-BinExporter/glTFExportOptions.cs +++ b/glTF-BinExporter/glTFExportOptions.cs @@ -17,6 +17,10 @@ public class glTFExportOptions public int SubDLevel = glTFBinExporterPlugin.SubDLevelDefault; public bool ExportTextureCoordinates = glTFBinExporterPlugin.ExportTextureCoordinatesDefault; + public int UV0 = glTFBinExporterPlugin.UV0Default; + public int UV1 = glTFBinExporterPlugin.UV1Default; + public bool ExportAllTextureCoordinates = glTFBinExporterPlugin.ExportAllTextureCoordinatesDefault; + public bool ExportVertexNormals = glTFBinExporterPlugin.ExportVertexNormalsDefault; public bool ExportOpenMeshes = glTFBinExporterPlugin.ExportOpenMeshesDefault; public bool ExportVertexColors = glTFBinExporterPlugin.ExportVertexColorsDefault; diff --git a/glTF-BinExporter/glTFExportOptionsDialog.cs b/glTF-BinExporter/glTFExportOptionsDialog.cs index ed62139..03b7091 100644 --- a/glTF-BinExporter/glTFExportOptionsDialog.cs +++ b/glTF-BinExporter/glTFExportOptionsDialog.cs @@ -23,6 +23,14 @@ class ExportOptionsDialog : Dialog private Slider subdLevel = new Slider(); private CheckBox exportTextureCoordinates = new CheckBox(); + private GroupBox textureChannelsBox = new GroupBox(); + private Label uv0Label = new Label(); + private NumericStepper uv0 = new NumericStepper(); + private Label uv1Label = new Label(); + private NumericStepper uv1 = new NumericStepper(); + private CheckBox exportAllTextureChannels = new CheckBox(); + private Label uvWarningLabel = new Label(); + private CheckBox exportVertexNormals = new CheckBox(); private CheckBox exportOpenMeshes = new CheckBox(); private CheckBox exportVertexColors = new CheckBox(); @@ -78,8 +86,40 @@ public ExportOptionsDialog() } }; + textureChannelsBox.Text = "Texture Channels"; + exportTextureCoordinates.Text = "Export texture coordinates"; + uv0Label.Text = "UV0 Channel"; + + uv0.ToolTip = "0 = Default"; + uv0.DecimalPlaces = 0; + uv0.MinValue = 0; + + uv1Label.Text = "UV1 Channel"; + + uv1.ToolTip = "0 = Default"; + uv1.DecimalPlaces = 0; + uv1.MinValue = 0; + + exportAllTextureChannels.Text = "Export all texture channels (unsupported)"; + + textureChannelsBox.Content = new TableLayout() + { + Padding = DefaultPadding, + Spacing = DefaultSpacing, + Rows = + { + new TableRow(uv0Label, uv0), + new TableRow(uv1Label, uv1), + new TableRow(exportAllTextureChannels) + } + }; + + uvWarningLabel.Text = "Warning! These textures are getting merged:\n" + + "- Color and alpha\n" + + "- Metalness and Roughness"; + exportVertexNormals.Text = "Export vertex normals"; exportOpenMeshes.Text = "Export open meshes"; @@ -106,6 +146,9 @@ public ExportOptionsDialog() useDracoCompressionCheck.CheckedChanged += UseDracoCompressionCheck_CheckedChanged; exportMaterials.CheckedChanged += ExportMaterials_CheckedChanged; + exportTextureCoordinates.CheckedChanged += ExportTextureCoordinates_CheckedChanged; + exportAllTextureChannels.CheckedChanged += ExportAllTextureChannels_CheckedChanged; + useSubdControlNet.CheckedChanged += UseSubdControlNet_CheckedChanged; cancelButton.Click += CancelButton_Click; @@ -173,6 +216,24 @@ public ExportOptionsDialog() tabControl.Pages.Add(meshPage); + TabPage textureCoordinatesPage = new TabPage() + { + Text = "UVs", + Content = new TableLayout() + { + Padding = DefaultPadding, + Spacing = DefaultSpacing, + Rows = + { + new TableRow(exportTextureCoordinates), + new TableRow(textureChannelsBox), + new TableRow(uvWarningLabel) + }, + }, + }; + + tabControl.Pages.Add(textureCoordinatesPage); + TabPage compressionPage = new TabPage() { Text = "Compression", @@ -203,6 +264,7 @@ public ExportOptionsDialog() }; } + private void OptionsToDialog() { useSettingsDontShowDialogCheck.Checked = glTFBinExporterPlugin.UseSavedSettingsDontShowDialog; @@ -221,6 +283,12 @@ private void OptionsToDialog() subdLevel.Value = glTFBinExporterPlugin.SubDLevel; exportTextureCoordinates.Checked = glTFBinExporterPlugin.ExportTextureCoordinates; + EnableDisableTextureChannelControls(glTFBinExporterPlugin.ExportTextureCoordinates); + uv0.Value = glTFBinExporterPlugin.UV0; + uv1.Value = glTFBinExporterPlugin.UV1; + exportAllTextureChannels.Checked = glTFBinExporterPlugin.ExportAllTextureCoordinates; + EnableDisableUVControls(glTFBinExporterPlugin.ExportAllTextureCoordinates); + exportVertexNormals.Checked = glTFBinExporterPlugin.ExportVertexNormals; exportOpenMeshes.Checked = glTFBinExporterPlugin.ExportOpenMeshes; exportVertexColors.Checked = glTFBinExporterPlugin.ExportVertexColors; @@ -249,6 +317,10 @@ private void DialogToOptions() glTFBinExporterPlugin.SubDLevel = subdLevel.Value; glTFBinExporterPlugin.ExportTextureCoordinates = GetCheckboxValue(exportTextureCoordinates); + glTFBinExporterPlugin.UV0 = (int)uv0.Value; + glTFBinExporterPlugin.UV1 = (int)uv1.Value; + glTFBinExporterPlugin.ExportAllTextureCoordinates = GetCheckboxValue(exportAllTextureChannels); + glTFBinExporterPlugin.ExportVertexNormals = GetCheckboxValue(exportVertexNormals); glTFBinExporterPlugin.ExportOpenMeshes = GetCheckboxValue(exportOpenMeshes); glTFBinExporterPlugin.ExportVertexColors = GetCheckboxValue(exportVertexColors); @@ -296,6 +368,30 @@ private void EnableDisableMaterialControls(bool enabled) { useDisplayColorForUnsetMaterial.Enabled = enabled; } + private void ExportTextureCoordinates_CheckedChanged(object sender, EventArgs e) + { + bool enabled = GetCheckboxValue(exportTextureCoordinates); + + EnableDisableTextureChannelControls(enabled); + } + + private void EnableDisableTextureChannelControls(bool enabled) + { + textureChannelsBox.Enabled = enabled; + } + + private void ExportAllTextureChannels_CheckedChanged(object sender, EventArgs e) + { + bool enabled = GetCheckboxValue(exportAllTextureChannels); + + EnableDisableUVControls(enabled); + } + + private void EnableDisableUVControls(bool enabled) + { + uv0.Enabled = !enabled; + uv1.Enabled = !enabled; + } private void UseSubdControlNet_CheckedChanged(object sender, EventArgs e) { From 770277e02fd26002d927ff6c5d1aca1fa1ff789c Mon Sep 17 00:00:00 2001 From: Peter Krattenmacher Date: Sun, 22 Aug 2021 14:41:31 +0200 Subject: [PATCH 06/19] Fixes. --- glTF-BinExporter/RhinoMeshGltfConverter.cs | 8 ++++---- glTF-BinExporter/glTFBinExporterPlugin.cs | 4 ++++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/glTF-BinExporter/RhinoMeshGltfConverter.cs b/glTF-BinExporter/RhinoMeshGltfConverter.cs index aa6796c..4e856b8 100644 --- a/glTF-BinExporter/RhinoMeshGltfConverter.cs +++ b/glTF-BinExporter/RhinoMeshGltfConverter.cs @@ -157,7 +157,7 @@ private void PreprocessMesh(Mesh rhinoMesh) var defaultTextureCoordinates = rhinoMesh.TextureCoordinates; int textureCoordinatesAccessorIdx = -1; - if (textureMappings[0] == null) + if (textureMappings.Length == 0 || textureMappings[0] == null) { textureCoordinatesAccessorIdx = GetTextureCoordinatesAccessor(defaultTextureCoordinates); primitive.Attributes.Add(Constants.TexCoord0AttributeTag, textureCoordinatesAccessorIdx); @@ -168,7 +168,7 @@ private void PreprocessMesh(Mesh rhinoMesh) int newTextureCoordinatesAccessorIdx = GetTextureCoordinatesAccessor(rhinoMesh.TextureCoordinates); primitive.Attributes.Add(Constants.TexCoord0AttributeTag, newTextureCoordinatesAccessorIdx); } - if (textureMappings[1] == null && options.UV1 == 0 && options.UV0 != options.UV1) + if ((textureMappings.Length < 2 || textureMappings[1] == null) && options.UV1 == 0 && options.UV0 != options.UV1) { if (textureCoordinatesAccessorIdx == -1) { @@ -180,7 +180,7 @@ private void PreprocessMesh(Mesh rhinoMesh) primitive.Attributes.Add(Constants.TexCoord1AttributeTag, textureCoordinatesAccessorIdx); } } - else if(options.UV0 != options.UV1) + else if(textureMappings.Length > 1 && options.UV0 != options.UV1) { rhinoMesh.SetTextureCoordinates(textureMappings[1], exportData.ObjectTransform, false); int newTextureCoordinatesAccessorIdx = GetTextureCoordinatesAccessor(rhinoMesh.TextureCoordinates); @@ -213,7 +213,7 @@ private void PreprocessMesh(Mesh rhinoMesh) { dracoCompressionObject.Attributes.Add(Constants.TexCoord0AttributeTag, currentGeometryInfo.TextureCoordinatesAttributePosition); - for (int j = 1; j <= textureMappings.Length; j++) + for (int j = 1; j < textureMappings.Length; j++) { dracoCompressionObject.Attributes.Add("TEXCOORD_" + j, currentGeometryInfo.TextureCoordinatesAttributePosition); } diff --git a/glTF-BinExporter/glTFBinExporterPlugin.cs b/glTF-BinExporter/glTFBinExporterPlugin.cs index 844d488..5cf4d2a 100644 --- a/glTF-BinExporter/glTFBinExporterPlugin.cs +++ b/glTF-BinExporter/glTFBinExporterPlugin.cs @@ -267,6 +267,10 @@ public static glTFExportOptions GetSavedOptions() SubDLevel = SubDLevel, ExportTextureCoordinates = ExportTextureCoordinates, + UV0 = UV0, + UV1 = UV1, + ExportAllTextureCoordinates = ExportAllTextureCoordinates, + ExportVertexNormals = ExportVertexNormals, ExportOpenMeshes = ExportOpenMeshes, ExportVertexColors = ExportVertexColors, From b60665a606dd62218cededda79d4cadd86b6fed7 Mon Sep 17 00:00:00 2001 From: Joshua Kennedy Date: Mon, 23 Aug 2021 11:04:04 +0300 Subject: [PATCH 07/19] Store the RhinoDoc on the RhinoDocGltfConverter --- glTF-BinExporter/GlTFExporterCommand.cs | 6 +++--- glTF-BinExporter/RhinoDocGltfConverter.cs | 6 +++++- glTF-BinExporter/glTFBinExporterPlugin.cs | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/glTF-BinExporter/GlTFExporterCommand.cs b/glTF-BinExporter/GlTFExporterCommand.cs index 650ca0b..b8c854c 100644 --- a/glTF-BinExporter/GlTFExporterCommand.cs +++ b/glTF-BinExporter/GlTFExporterCommand.cs @@ -47,7 +47,7 @@ protected override Result RunCommand(Rhino.RhinoDoc doc, RunMode mode) Rhino.DocObjects.RhinoObject[] rhinoObjects = go.Objects().Select(o => o.Object()).ToArray(); - if(!DoExport(dialog.FileName, opts, binary, rhinoObjects, doc.RenderSettings.LinearWorkflow)) + if(!DoExport(dialog.FileName, opts, binary, doc, rhinoObjects, doc.RenderSettings.LinearWorkflow)) { return Result.Failure; } @@ -132,9 +132,9 @@ private SaveFileDialog GetSaveFileDialog() }; } - public static bool DoExport(string fileName, glTFExportOptions options, bool binary, IEnumerable rhinoObjects, Rhino.Render.LinearWorkflow workflow) + public static bool DoExport(string fileName, glTFExportOptions options, bool binary, RhinoDoc doc, IEnumerable rhinoObjects, Rhino.Render.LinearWorkflow workflow) { - RhinoDocGltfConverter converter = new RhinoDocGltfConverter(options, binary, rhinoObjects, workflow); + RhinoDocGltfConverter converter = new RhinoDocGltfConverter(options, binary, doc, rhinoObjects, workflow); glTFLoader.Schema.Gltf gltf = converter.ConvertToGltf(); if (binary) diff --git a/glTF-BinExporter/RhinoDocGltfConverter.cs b/glTF-BinExporter/RhinoDocGltfConverter.cs index 14e76e7..667d416 100644 --- a/glTF-BinExporter/RhinoDocGltfConverter.cs +++ b/glTF-BinExporter/RhinoDocGltfConverter.cs @@ -18,8 +18,9 @@ public struct ObjectExportData class RhinoDocGltfConverter { - public RhinoDocGltfConverter(glTFExportOptions options, bool binary, IEnumerable objects, LinearWorkflow workflow) + public RhinoDocGltfConverter(glTFExportOptions options, bool binary, RhinoDoc doc, IEnumerable objects, LinearWorkflow workflow) { + this.doc = doc; this.options = options; this.binary = binary; this.objects = objects; @@ -28,12 +29,15 @@ public RhinoDocGltfConverter(glTFExportOptions options, bool binary, IEnumerable public RhinoDocGltfConverter(glTFExportOptions options, bool binary, RhinoDoc doc, LinearWorkflow workflow) { + this.doc = doc; this.options = options; this.binary = binary; this.objects = doc.Objects; this.workflow = null; } + private RhinoDoc doc = null; + private IEnumerable objects = null; private bool binary = false; diff --git a/glTF-BinExporter/glTFBinExporterPlugin.cs b/glTF-BinExporter/glTFBinExporterPlugin.cs index 20995fd..330e846 100644 --- a/glTF-BinExporter/glTFBinExporterPlugin.cs +++ b/glTF-BinExporter/glTFBinExporterPlugin.cs @@ -54,7 +54,7 @@ protected override WriteFileResult WriteFile(string filename, int index, RhinoDo IEnumerable objects = GetObjectsToExport(doc, options); - if(!GlTFExporterCommand.DoExport(filename, exportOptions, binary, objects, doc.RenderSettings.LinearWorkflow)) + if(!GlTFExporterCommand.DoExport(filename, exportOptions, binary, doc, objects, doc.RenderSettings.LinearWorkflow)) { return WriteFileResult.Failure; } From c879f6c0e12125a5f1b34176d1cfe80bdb12aa8a Mon Sep 17 00:00:00 2001 From: Peter Krattenmacher Date: Mon, 23 Aug 2021 10:22:11 +0200 Subject: [PATCH 08/19] Use stored RhinoDoc instead of ActiveDoc. --- glTF-BinExporter/RhinoDocGltfConverter.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/glTF-BinExporter/RhinoDocGltfConverter.cs b/glTF-BinExporter/RhinoDocGltfConverter.cs index 667d416..eec4841 100644 --- a/glTF-BinExporter/RhinoDocGltfConverter.cs +++ b/glTF-BinExporter/RhinoDocGltfConverter.cs @@ -100,7 +100,7 @@ public Gltf ConvertToGltf() if (options.ExportLayers) { - AddToLayer(RhinoDoc.ActiveDoc.Layers[exportData.Object.Attributes.LayerIndex], nodeIndex); + AddToLayer(doc.Layers[exportData.Object.Attributes.LayerIndex], nodeIndex); } else { @@ -144,7 +144,7 @@ private void AddToLayer(Layer layer, int child) layers.Add(layer.Index, node); int nodeIndex = dummy.Nodes.AddAndReturnIndex(node); - Layer parentLayer = RhinoDoc.ActiveDoc.Layers.FindId(layer.ParentLayerId); + Layer parentLayer = doc.Layers.FindId(layer.ParentLayerId); if (parentLayer == null) { @@ -232,7 +232,7 @@ private int GetLayerMaterial(RhinoObject rhinoObject) if (!layerMaterialIndices.TryGetValue(rhinoObject.Attributes.LayerIndex, out int layerMaterialIndex)) { Color4f objectColor = GetObjectColor(rhinoObject); - layerMaterialIndex = CreateSolidColorMaterial(objectColor, RhinoDoc.ActiveDoc.Layers[rhinoObject.Attributes.LayerIndex].Name); + layerMaterialIndex = CreateSolidColorMaterial(objectColor, doc.Layers[rhinoObject.Attributes.LayerIndex].Name); layerMaterialIndices.Add(rhinoObject.Attributes.LayerIndex, layerMaterialIndex); } return layerMaterialIndex; @@ -258,7 +258,7 @@ Color4f GetObjectColor(RhinoObject rhinoObject) { int layerIndex = rhinoObject.Attributes.LayerIndex; - return new Color4f(RhinoDoc.ActiveDoc.Layers[layerIndex].Color); + return new Color4f(doc.Layers[layerIndex].Color); } else { From d12d92a4ff07f463ad185d5563aa4b72eb971369 Mon Sep 17 00:00:00 2001 From: Peter Krattenmacher Date: Mon, 23 Aug 2021 12:46:10 +0200 Subject: [PATCH 09/19] Add GetLayerColor method. --- glTF-BinExporter/RhinoDocGltfConverter.cs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/glTF-BinExporter/RhinoDocGltfConverter.cs b/glTF-BinExporter/RhinoDocGltfConverter.cs index eec4841..00dd444 100644 --- a/glTF-BinExporter/RhinoDocGltfConverter.cs +++ b/glTF-BinExporter/RhinoDocGltfConverter.cs @@ -231,7 +231,7 @@ private int GetLayerMaterial(RhinoObject rhinoObject) { if (!layerMaterialIndices.TryGetValue(rhinoObject.Attributes.LayerIndex, out int layerMaterialIndex)) { - Color4f objectColor = GetObjectColor(rhinoObject); + Color4f objectColor = GetLayerColor(rhinoObject); layerMaterialIndex = CreateSolidColorMaterial(objectColor, doc.Layers[rhinoObject.Attributes.LayerIndex].Name); layerMaterialIndices.Add(rhinoObject.Attributes.LayerIndex, layerMaterialIndex); } @@ -256,9 +256,7 @@ Color4f GetObjectColor(RhinoObject rhinoObject) { if (rhinoObject.Attributes.ColorSource == ObjectColorSource.ColorFromLayer) { - int layerIndex = rhinoObject.Attributes.LayerIndex; - - return new Color4f(doc.Layers[layerIndex].Color); + return GetLayerColor(rhinoObject); } else { @@ -266,6 +264,12 @@ Color4f GetObjectColor(RhinoObject rhinoObject) } } + Color4f GetLayerColor(RhinoObject rhinoObject) + { + int layerIndex = rhinoObject.Attributes.LayerIndex; + return new Color4f(doc.Layers[layerIndex].Color); + } + public Rhino.Geometry.Mesh[] GetMeshes(RhinoObject rhinoObject) { From d580c7253965f76d2715632074cfc380b93d0c71 Mon Sep 17 00:00:00 2001 From: Peter Krattenmacher Date: Mon, 23 Aug 2021 13:22:22 +0200 Subject: [PATCH 10/19] Move options.ExportMaterials outside of the GetMaterials function. --- glTF-BinExporter/RhinoDocGltfConverter.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/glTF-BinExporter/RhinoDocGltfConverter.cs b/glTF-BinExporter/RhinoDocGltfConverter.cs index 00dd444..458f669 100644 --- a/glTF-BinExporter/RhinoDocGltfConverter.cs +++ b/glTF-BinExporter/RhinoDocGltfConverter.cs @@ -85,7 +85,8 @@ public Gltf ConvertToGltf() foreach (ObjectExportData exportData in sanitized) { - int[] materialIndices = GetMaterials(exportData.RenderMaterials, exportData.Object); + int[] materialIndices = null; + if(options.ExportMaterials) materialIndices = GetMaterials(exportData.RenderMaterials, exportData.Object); RhinoMeshGltfConverter meshConverter = new RhinoMeshGltfConverter(exportData, materialIndices, options, binary, dummy, binaryBuffer); int meshIndex = meshConverter.AddMesh(); From 4497214f807f9e7555bd1c88d7a18cdb7dce768b Mon Sep 17 00:00:00 2001 From: Peter Krattenmacher Date: Mon, 23 Aug 2021 13:38:30 +0200 Subject: [PATCH 11/19] Rewrite GetMaterials. --- glTF-BinExporter/RhinoDocGltfConverter.cs | 71 ++++++++++++----------- 1 file changed, 38 insertions(+), 33 deletions(-) diff --git a/glTF-BinExporter/RhinoDocGltfConverter.cs b/glTF-BinExporter/RhinoDocGltfConverter.cs index 458f669..3f2fa65 100644 --- a/glTF-BinExporter/RhinoDocGltfConverter.cs +++ b/glTF-BinExporter/RhinoDocGltfConverter.cs @@ -54,6 +54,8 @@ public RhinoDocGltfConverter(glTFExportOptions options, bool binary, RhinoDoc do private Dictionary layerMaterialIndices = new Dictionary(); + private int defaultMaterialIndex = -1; + public Gltf ConvertToGltf() { dummy.Scene = 0; @@ -175,59 +177,62 @@ int[] GetMaterials(RenderMaterial[] materials, RhinoObject rhinoObject) Dictionary colorIndices = new Dictionary(); - for (int i = 0; i < materials.Length; i++) + for (int i = 0; i < subObjects.Length; i++) { var material = materials[i]; - if (!options.ExportMaterials) - { - return null; - } - - Guid materialId; - if (material == null && options.UseDisplayColorForUnsetMaterials) + if(material == null) { - if (options.ExportLayers) + if(options.UseDisplayColorForUnsetMaterials) { - if (subObjects[i].Attributes.ColorSource == ObjectColorSource.ColorFromLayer) + if(subObjects[i].Attributes.ColorSource == ObjectColorSource.ColorFromLayer) { materialIndices[i] = GetLayerMaterial(rhinoObject); - continue; + } + else + { + Color4f objectColor = GetObjectColor(subObjects[i]); + if (!colorIndices.TryGetValue(objectColor, out int colorIndex)) + { + colorIndex = CreateSolidColorMaterial(objectColor, GetObjectName(rhinoObject)); + colorIndices.Add(objectColor, colorIndex); + } + materialIndices[i] = colorIndex; } } - - Color4f objectColor = GetObjectColor(subObjects[i]); - if (!colorIndices.TryGetValue(objectColor, out int colorIndex)) + else { - colorIndex = CreateSolidColorMaterial(objectColor, GetObjectName(rhinoObject)); - colorIndices.Add(objectColor, colorIndex); + materialIndices[i] = GetDefaultMaterial(); } - materialIndices[i] = colorIndex; - continue; - } - else if (material == null) - { - material = Rhino.DocObjects.Material.DefaultMaterial.RenderMaterial; - materialId = new Guid(); } else { - materialId = material.Id; - } - - if (!materialsMap.TryGetValue(materialId, out int materialIndex)) - { - RhinoMaterialGltfConverter materialConverter = new RhinoMaterialGltfConverter(options, binary, dummy, binaryBuffer, material, workflow); - materialIndex = materialConverter.AddMaterial(); - materialsMap.Add(materialId, materialIndex); + Guid materialId = material.Id; + if (!materialsMap.TryGetValue(materialId, out int materialIndex)) + { + RhinoMaterialGltfConverter materialConverter = new RhinoMaterialGltfConverter(options, binary, dummy, binaryBuffer, material, workflow); + materialIndex = materialConverter.AddMaterial(); + materialsMap.Add(materialId, materialIndex); + } + materialIndices[i] = materialIndex; } - - materialIndices[i] = materialIndex; } return materialIndices; } + private int GetDefaultMaterial() + { + if(defaultMaterialIndex == -1) + { + RenderMaterial material = Rhino.DocObjects.Material.DefaultMaterial.RenderMaterial; + material.Name = "DefaultMaterial"; + RhinoMaterialGltfConverter materialConverter = new RhinoMaterialGltfConverter(options, binary, dummy, binaryBuffer, material, workflow); + defaultMaterialIndex = materialConverter.AddMaterial(); + } + return defaultMaterialIndex; + } + private int GetLayerMaterial(RhinoObject rhinoObject) { if (!layerMaterialIndices.TryGetValue(rhinoObject.Attributes.LayerIndex, out int layerMaterialIndex)) From 28b49e2a54bd1ca6b47c0142bea30e8ee34096b2 Mon Sep 17 00:00:00 2001 From: Peter Krattenmacher Date: Mon, 23 Aug 2021 13:56:39 +0200 Subject: [PATCH 12/19] Add GetColorMaterial. Change Color4f to Color. --- glTF-BinExporter/RhinoDocGltfConverter.cs | 33 ++++++++++++++--------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/glTF-BinExporter/RhinoDocGltfConverter.cs b/glTF-BinExporter/RhinoDocGltfConverter.cs index 3f2fa65..c03119f 100644 --- a/glTF-BinExporter/RhinoDocGltfConverter.cs +++ b/glTF-BinExporter/RhinoDocGltfConverter.cs @@ -5,6 +5,7 @@ using Rhino.Render; using System; using System.Collections.Generic; +using System.Drawing; using System.Linq; namespace glTF_BinExporter @@ -175,7 +176,7 @@ int[] GetMaterials(RenderMaterial[] materials, RhinoObject rhinoObject) RhinoObject[] subObjects = rhinoObject.GetSubObjects(); int[] materialIndices = new int[materials.Length]; - Dictionary colorIndices = new Dictionary(); + Dictionary colorIndices = new Dictionary(); for (int i = 0; i < subObjects.Length; i++) { @@ -191,13 +192,7 @@ int[] GetMaterials(RenderMaterial[] materials, RhinoObject rhinoObject) } else { - Color4f objectColor = GetObjectColor(subObjects[i]); - if (!colorIndices.TryGetValue(objectColor, out int colorIndex)) - { - colorIndex = CreateSolidColorMaterial(objectColor, GetObjectName(rhinoObject)); - colorIndices.Add(objectColor, colorIndex); - } - materialIndices[i] = colorIndex; + materialIndices[i] = GetColorMaterial(subObjects[i], colorIndices); } } else @@ -221,6 +216,18 @@ int[] GetMaterials(RenderMaterial[] materials, RhinoObject rhinoObject) return materialIndices; } + private int GetColorMaterial(RhinoObject rhinoObject, Dictionary colorMaterials) + { + Color objectColor = GetObjectColor(rhinoObject); + int colorIndex = objectColor.ToArgb(); + if (!colorMaterials.TryGetValue(colorIndex, out int colorMaterialIndex)) + { + colorMaterialIndex = CreateSolidColorMaterial(new Color4f(objectColor), GetObjectName(rhinoObject)); + colorMaterials.Add(colorIndex, colorIndex); + } + return colorMaterialIndex; + } + private int GetDefaultMaterial() { if(defaultMaterialIndex == -1) @@ -237,7 +244,7 @@ private int GetLayerMaterial(RhinoObject rhinoObject) { if (!layerMaterialIndices.TryGetValue(rhinoObject.Attributes.LayerIndex, out int layerMaterialIndex)) { - Color4f objectColor = GetLayerColor(rhinoObject); + Color4f objectColor = new Color4f(GetLayerColor(rhinoObject)); layerMaterialIndex = CreateSolidColorMaterial(objectColor, doc.Layers[rhinoObject.Attributes.LayerIndex].Name); layerMaterialIndices.Add(rhinoObject.Attributes.LayerIndex, layerMaterialIndex); } @@ -258,7 +265,7 @@ int CreateSolidColorMaterial(Color4f color, string name) return dummy.Materials.AddAndReturnIndex(material); } - Color4f GetObjectColor(RhinoObject rhinoObject) + Color GetObjectColor(RhinoObject rhinoObject) { if (rhinoObject.Attributes.ColorSource == ObjectColorSource.ColorFromLayer) { @@ -266,14 +273,14 @@ Color4f GetObjectColor(RhinoObject rhinoObject) } else { - return new Color4f(rhinoObject.Attributes.ObjectColor); + return rhinoObject.Attributes.ObjectColor; } } - Color4f GetLayerColor(RhinoObject rhinoObject) + Color GetLayerColor(RhinoObject rhinoObject) { int layerIndex = rhinoObject.Attributes.LayerIndex; - return new Color4f(doc.Layers[layerIndex].Color); + return doc.Layers[layerIndex].Color; } public Rhino.Geometry.Mesh[] GetMeshes(RhinoObject rhinoObject) From cf27ee360418e6c0cf25b21e635c7bb35cc2ac7c Mon Sep 17 00:00:00 2001 From: Peter Krattenmacher Date: Mon, 23 Aug 2021 14:35:37 +0200 Subject: [PATCH 13/19] Share color materials of all objects. --- glTF-BinExporter/RhinoDocGltfConverter.cs | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/glTF-BinExporter/RhinoDocGltfConverter.cs b/glTF-BinExporter/RhinoDocGltfConverter.cs index c03119f..dea1dd8 100644 --- a/glTF-BinExporter/RhinoDocGltfConverter.cs +++ b/glTF-BinExporter/RhinoDocGltfConverter.cs @@ -55,6 +55,8 @@ public RhinoDocGltfConverter(glTFExportOptions options, bool binary, RhinoDoc do private Dictionary layerMaterialIndices = new Dictionary(); + private Dictionary colorMaterials = new Dictionary(); + private int defaultMaterialIndex = -1; public Gltf ConvertToGltf() @@ -176,8 +178,6 @@ int[] GetMaterials(RenderMaterial[] materials, RhinoObject rhinoObject) RhinoObject[] subObjects = rhinoObject.GetSubObjects(); int[] materialIndices = new int[materials.Length]; - Dictionary colorIndices = new Dictionary(); - for (int i = 0; i < subObjects.Length; i++) { var material = materials[i]; @@ -192,7 +192,7 @@ int[] GetMaterials(RenderMaterial[] materials, RhinoObject rhinoObject) } else { - materialIndices[i] = GetColorMaterial(subObjects[i], colorIndices); + materialIndices[i] = GetColorMaterial(subObjects[i]); } } else @@ -216,18 +216,30 @@ int[] GetMaterials(RenderMaterial[] materials, RhinoObject rhinoObject) return materialIndices; } - private int GetColorMaterial(RhinoObject rhinoObject, Dictionary colorMaterials) + private int GetColorMaterial(RhinoObject rhinoObject) { Color objectColor = GetObjectColor(rhinoObject); int colorIndex = objectColor.ToArgb(); if (!colorMaterials.TryGetValue(colorIndex, out int colorMaterialIndex)) { - colorMaterialIndex = CreateSolidColorMaterial(new Color4f(objectColor), GetObjectName(rhinoObject)); + colorMaterialIndex = CreateSolidColorMaterial(new Color4f(objectColor), GetColorName(objectColor)); colorMaterials.Add(colorIndex, colorIndex); } return colorMaterialIndex; } + private string GetColorName(Color color) + { + if (color.IsNamedColor) + { + return color.Name; + } + else + { + return color.ToString(); + } + } + private int GetDefaultMaterial() { if(defaultMaterialIndex == -1) From 70ec7ef8c3fae22d977d7cc38e722d75470538ac Mon Sep 17 00:00:00 2001 From: Peter Krattenmacher Date: Tue, 24 Aug 2021 12:10:17 +0200 Subject: [PATCH 14/19] Cleaner sub-object support. --- glTF-BinExporter/RhinoDocGltfConverter.cs | 57 ++++++++++++++--------- 1 file changed, 35 insertions(+), 22 deletions(-) diff --git a/glTF-BinExporter/RhinoDocGltfConverter.cs b/glTF-BinExporter/RhinoDocGltfConverter.cs index dea1dd8..600302b 100644 --- a/glTF-BinExporter/RhinoDocGltfConverter.cs +++ b/glTF-BinExporter/RhinoDocGltfConverter.cs @@ -91,7 +91,7 @@ public Gltf ConvertToGltf() foreach (ObjectExportData exportData in sanitized) { int[] materialIndices = null; - if(options.ExportMaterials) materialIndices = GetMaterials(exportData.RenderMaterials, exportData.Object); + if (options.ExportMaterials) materialIndices = GetMaterials(exportData.RenderMaterials, exportData.Object); RhinoMeshGltfConverter meshConverter = new RhinoMeshGltfConverter(exportData, materialIndices, options, binary, dummy, binaryBuffer); int meshIndex = meshConverter.AddMesh(); @@ -176,15 +176,16 @@ public byte[] GetBinaryBuffer() int[] GetMaterials(RenderMaterial[] materials, RhinoObject rhinoObject) { RhinoObject[] subObjects = rhinoObject.GetSubObjects(); + if (subObjects.Length == 0) subObjects = new RhinoObject[1] { rhinoObject }; int[] materialIndices = new int[materials.Length]; - for (int i = 0; i < subObjects.Length; i++) + for (int i = 0; i < materials.Length; i++) { var material = materials[i]; - if(material == null) + if (material == null) { - if(options.UseDisplayColorForUnsetMaterials) + if (options.UseDisplayColorForUnsetMaterials) { if(subObjects[i].Attributes.ColorSource == ObjectColorSource.ColorFromLayer) { @@ -223,7 +224,7 @@ private int GetColorMaterial(RhinoObject rhinoObject) if (!colorMaterials.TryGetValue(colorIndex, out int colorMaterialIndex)) { colorMaterialIndex = CreateSolidColorMaterial(new Color4f(objectColor), GetColorName(objectColor)); - colorMaterials.Add(colorIndex, colorIndex); + colorMaterials.Add(colorIndex, colorMaterialIndex); } return colorMaterialIndex; } @@ -242,7 +243,7 @@ private string GetColorName(Color color) private int GetDefaultMaterial() { - if(defaultMaterialIndex == -1) + if (defaultMaterialIndex == -1) { RenderMaterial material = Rhino.DocObjects.Material.DefaultMaterial.RenderMaterial; material.Name = "DefaultMaterial"; @@ -328,10 +329,26 @@ public Rhino.Geometry.Mesh[] GetMeshes(RhinoObject rhinoObject) // Need to get a Mesh from the None-mesh object. Using the FastRenderMesh here. Could be made configurable. // First make sure the internal rhino mesh has been created - //rhinoObject.CreateMeshes(Rhino.Geometry.MeshType.Preview, Rhino.Geometry.MeshingParameters.FastRenderMesh, true); + rhinoObject.CreateMeshes(Rhino.Geometry.MeshType.Preview, Rhino.Geometry.MeshingParameters.FastRenderMesh, true); // Then get the internal rhino meshes - Rhino.Geometry.Mesh[] meshes = rhinoObject.GetMeshes(Rhino.Geometry.MeshType.Preview); + //Rhino.Geometry.Mesh[] meshes = rhinoObject.GetMeshes(Rhino.Geometry.MeshType.Preview); + + var subObjects = rhinoObject.GetSubObjects(); + if (subObjects.Length == 0) subObjects = new RhinoObject[1] { rhinoObject }; + Rhino.Geometry.Mesh[] meshes = new Rhino.Geometry.Mesh[subObjects.Length]; + + for (int i = 0; i < subObjects.Length; i++) + { + var subMeshes = subObjects[i].GetMeshes(Rhino.Geometry.MeshType.Preview); + if(subMeshes.Length == 0) + { + subObjects[i].CreateMeshes(Rhino.Geometry.MeshType.Preview, Rhino.Geometry.MeshingParameters.FastRenderMesh, true); + subMeshes = subObjects[i].GetMeshes(Rhino.Geometry.MeshType.Preview); + + } + meshes[i] = subMeshes[0]; + } List validMeshes = new List(); @@ -400,23 +417,19 @@ public List SanitizeRhinoObjects(IEnumerable rhin // Need to get a Mesh from the None-mesh object. Using the FastRenderMesh here. Could be made configurable. // First make sure the internal rhino mesh has been created - rhinoObject.CreateMeshes(Rhino.Geometry.MeshType.Preview, Rhino.Geometry.MeshingParameters.FastRenderMesh, true); + //rhinoObject.CreateMeshes(Rhino.Geometry.MeshType.Preview, Rhino.Geometry.MeshingParameters.FastRenderMesh, true); - var mats = new RenderMaterial[rhinoObject.MeshCount(Rhino.Geometry.MeshType.Preview, Rhino.Geometry.MeshingParameters.FastRenderMesh)]; - for (int i = 0; i < mats.Length; i++) - { - foreach (var component in rhinoObject.SubobjectMaterialComponents) - { - if (component.Index == i) - { - mats[i] = rhinoObject.GetRenderMaterial(component); - break; - } - } + var subObjects = rhinoObject.GetSubObjects(); + if (subObjects.Length == 0) subObjects = new RhinoObject[1] { rhinoObject }; + var mats = new RenderMaterial[subObjects.Length]; - if (mats[i] == null) + var components = rhinoObject.SubobjectMaterialComponents; + for (int i = 0; i < subObjects.Length; i++) + { + mats[i] = rhinoObject.RenderMaterial; + foreach (var component in components) { - mats[i] = rhinoObject.RenderMaterial; + if (component.Index == i) mats[i] = rhinoObject.GetRenderMaterial(component); } } From 5b1e7fc56e00d3ec05e9f47f8e4dafa354c90310 Mon Sep 17 00:00:00 2001 From: Peter Krattenmacher Date: Sun, 29 Aug 2021 13:04:00 +0200 Subject: [PATCH 15/19] Add support for layer materials. --- glTF-BinExporter/RhinoDocGltfConverter.cs | 39 +++++++++++++++-------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/glTF-BinExporter/RhinoDocGltfConverter.cs b/glTF-BinExporter/RhinoDocGltfConverter.cs index 600302b..98ae2a3 100644 --- a/glTF-BinExporter/RhinoDocGltfConverter.cs +++ b/glTF-BinExporter/RhinoDocGltfConverter.cs @@ -419,24 +419,11 @@ public List SanitizeRhinoObjects(IEnumerable rhin // First make sure the internal rhino mesh has been created //rhinoObject.CreateMeshes(Rhino.Geometry.MeshType.Preview, Rhino.Geometry.MeshingParameters.FastRenderMesh, true); - var subObjects = rhinoObject.GetSubObjects(); - if (subObjects.Length == 0) subObjects = new RhinoObject[1] { rhinoObject }; - var mats = new RenderMaterial[subObjects.Length]; - - var components = rhinoObject.SubobjectMaterialComponents; - for (int i = 0; i < subObjects.Length; i++) - { - mats[i] = rhinoObject.RenderMaterial; - foreach (var component in components) - { - if (component.Index == i) mats[i] = rhinoObject.GetRenderMaterial(component); - } - } - var isValidGeometry = Constants.ValidObjectTypes.Contains(rhinoObject.ObjectType); if (isValidGeometry && rhinoObject.ObjectType != ObjectType.InstanceReference) { + var mats = GetRenderMaterials(rhinoObject); var meshes = GetMeshes(rhinoObject); if (meshes.Length > 0) //Objects need a mesh to export @@ -461,6 +448,7 @@ public List SanitizeRhinoObjects(IEnumerable rhin // Transform the exploded geo into its correct place foreach (var item in objects.Zip(transforms, (rObj, trans) => (rhinoObject: rObj, trans))) { + var mats = GetRenderMaterials(item.rhinoObject); var meshes = GetMeshes(item.rhinoObject); foreach (var mesh in meshes) @@ -488,6 +476,29 @@ public List SanitizeRhinoObjects(IEnumerable rhin return rhinoObjectsRes; } + private RenderMaterial[] GetRenderMaterials(RhinoObject rhinoObject) + { + var subObjects = rhinoObject.GetSubObjects(); + if (subObjects.Length == 0) subObjects = new RhinoObject[1] { rhinoObject }; + var mats = new RenderMaterial[subObjects.Length]; + + var components = rhinoObject.SubobjectMaterialComponents; + for (int i = 0; i < subObjects.Length; i++) + { + mats[i] = rhinoObject.RenderMaterial; + foreach (var component in components) + { + if (component.Index == i) mats[i] = rhinoObject.GetRenderMaterial(component); + } + if (mats[i] == null) + { + mats[i] = doc.Layers[rhinoObject.Attributes.LayerIndex].RenderMaterial; + } + } + + return mats; + } + private void ExplodeRecursive(InstanceObject instanceObject, Rhino.Geometry.Transform instanceTransform, List pieces, List transforms) { for (int i = 0; i < instanceObject.InstanceDefinition.ObjectCount; i++) From 2b6ff8a2133b5a6194663f7fc58adbdf4ae1f490 Mon Sep 17 00:00:00 2001 From: Peter Krattenmacher Date: Sun, 29 Aug 2021 13:04:51 +0200 Subject: [PATCH 16/19] Add error checking in GetMeshes. --- glTF-BinExporter/RhinoDocGltfConverter.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/glTF-BinExporter/RhinoDocGltfConverter.cs b/glTF-BinExporter/RhinoDocGltfConverter.cs index 98ae2a3..cfbf5d6 100644 --- a/glTF-BinExporter/RhinoDocGltfConverter.cs +++ b/glTF-BinExporter/RhinoDocGltfConverter.cs @@ -345,9 +345,9 @@ public Rhino.Geometry.Mesh[] GetMeshes(RhinoObject rhinoObject) { subObjects[i].CreateMeshes(Rhino.Geometry.MeshType.Preview, Rhino.Geometry.MeshingParameters.FastRenderMesh, true); subMeshes = subObjects[i].GetMeshes(Rhino.Geometry.MeshType.Preview); - } - meshes[i] = subMeshes[0]; + if (subMeshes.Length == 1) meshes[i] = subMeshes[0]; + else if (subMeshes.Length > 1) RhinoApp.WriteLine("This shouldn't have happened: An sub object created more than one mesh! RhinoDocGltfConverter.cs line:349"); } List validMeshes = new List(); From 29898f2b31d61e7836a86a4ea4b286e9454ed574 Mon Sep 17 00:00:00 2001 From: Peter Krattenmacher Date: Sun, 29 Aug 2021 13:05:10 +0200 Subject: [PATCH 17/19] Fix support for InstanceObjects. --- glTF-BinExporter/RhinoDocGltfConverter.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/glTF-BinExporter/RhinoDocGltfConverter.cs b/glTF-BinExporter/RhinoDocGltfConverter.cs index cfbf5d6..0e27cfd 100644 --- a/glTF-BinExporter/RhinoDocGltfConverter.cs +++ b/glTF-BinExporter/RhinoDocGltfConverter.cs @@ -448,6 +448,14 @@ public List SanitizeRhinoObjects(IEnumerable rhin // Transform the exploded geo into its correct place foreach (var item in objects.Zip(transforms, (rObj, trans) => (rhinoObject: rObj, trans))) { + if (!doc.Layers[item.rhinoObject.Attributes.LayerIndex].IsVisible) continue; + + if (!item.rhinoObject.IsMeshable(Rhino.Geometry.MeshType.Any)) + { + RhinoApp.WriteLine("Skipping " + GetDebugName(item.rhinoObject) + ", object is not meshable. Object is a " + item.rhinoObject.ObjectType.ToString()); + continue; + } + var mats = GetRenderMaterials(item.rhinoObject); var meshes = GetMeshes(item.rhinoObject); From 137bd7440d65e966a74aa5eb082102f48c2deb67 Mon Sep 17 00:00:00 2001 From: Joshua Kennedy Date: Wed, 1 Sep 2021 09:48:06 +0300 Subject: [PATCH 18/19] Fix style on doc converter --- glTF-BinExporter/RhinoDocGltfConverter.cs | 73 ++++++++++++++++------- 1 file changed, 50 insertions(+), 23 deletions(-) diff --git a/glTF-BinExporter/RhinoDocGltfConverter.cs b/glTF-BinExporter/RhinoDocGltfConverter.cs index 0e27cfd..20d184c 100644 --- a/glTF-BinExporter/RhinoDocGltfConverter.cs +++ b/glTF-BinExporter/RhinoDocGltfConverter.cs @@ -57,7 +57,7 @@ public RhinoDocGltfConverter(glTFExportOptions options, bool binary, RhinoDoc do private Dictionary colorMaterials = new Dictionary(); - private int defaultMaterialIndex = -1; + private int? defaultMaterialIndex = null; public Gltf ConvertToGltf() { @@ -91,7 +91,11 @@ public Gltf ConvertToGltf() foreach (ObjectExportData exportData in sanitized) { int[] materialIndices = null; - if (options.ExportMaterials) materialIndices = GetMaterials(exportData.RenderMaterials, exportData.Object); + + if (options.ExportMaterials) + { + materialIndices = GetMaterials(exportData.RenderMaterials, exportData.Object); + } RhinoMeshGltfConverter meshConverter = new RhinoMeshGltfConverter(exportData, materialIndices, options, binary, dummy, binaryBuffer); int meshIndex = meshConverter.AddMesh(); @@ -165,7 +169,7 @@ private void AddToLayer(Layer layer, int child) public string GetObjectName(RhinoObject rhinoObject) { - return string.IsNullOrEmpty(rhinoObject.Name) ? null : rhinoObject.Name; + return string.IsNullOrEmpty(rhinoObject.Name) ? rhinoObject.Id.ToString() : rhinoObject.Name; } public byte[] GetBinaryBuffer() @@ -176,7 +180,12 @@ public byte[] GetBinaryBuffer() int[] GetMaterials(RenderMaterial[] materials, RhinoObject rhinoObject) { RhinoObject[] subObjects = rhinoObject.GetSubObjects(); - if (subObjects.Length == 0) subObjects = new RhinoObject[1] { rhinoObject }; + + if (subObjects.Length == 0) + { + subObjects = new RhinoObject[1] { rhinoObject }; + } + int[] materialIndices = new int[materials.Length]; for (int i = 0; i < materials.Length; i++) @@ -220,12 +229,15 @@ int[] GetMaterials(RenderMaterial[] materials, RhinoObject rhinoObject) private int GetColorMaterial(RhinoObject rhinoObject) { Color objectColor = GetObjectColor(rhinoObject); + int colorIndex = objectColor.ToArgb(); + if (!colorMaterials.TryGetValue(colorIndex, out int colorMaterialIndex)) { colorMaterialIndex = CreateSolidColorMaterial(new Color4f(objectColor), GetColorName(objectColor)); colorMaterials.Add(colorIndex, colorMaterialIndex); } + return colorMaterialIndex; } @@ -243,14 +255,15 @@ private string GetColorName(Color color) private int GetDefaultMaterial() { - if (defaultMaterialIndex == -1) + if (defaultMaterialIndex == null) { RenderMaterial material = Rhino.DocObjects.Material.DefaultMaterial.RenderMaterial; material.Name = "DefaultMaterial"; RhinoMaterialGltfConverter materialConverter = new RhinoMaterialGltfConverter(options, binary, dummy, binaryBuffer, material, workflow); defaultMaterialIndex = materialConverter.AddMaterial(); } - return defaultMaterialIndex; + + return defaultMaterialIndex.Value; } private int GetLayerMaterial(RhinoObject rhinoObject) @@ -335,19 +348,32 @@ public Rhino.Geometry.Mesh[] GetMeshes(RhinoObject rhinoObject) //Rhino.Geometry.Mesh[] meshes = rhinoObject.GetMeshes(Rhino.Geometry.MeshType.Preview); var subObjects = rhinoObject.GetSubObjects(); - if (subObjects.Length == 0) subObjects = new RhinoObject[1] { rhinoObject }; + + if (subObjects.Length == 0) + { + subObjects = new RhinoObject[1] { rhinoObject }; + } + Rhino.Geometry.Mesh[] meshes = new Rhino.Geometry.Mesh[subObjects.Length]; for (int i = 0; i < subObjects.Length; i++) { var subMeshes = subObjects[i].GetMeshes(Rhino.Geometry.MeshType.Preview); + if(subMeshes.Length == 0) { subObjects[i].CreateMeshes(Rhino.Geometry.MeshType.Preview, Rhino.Geometry.MeshingParameters.FastRenderMesh, true); subMeshes = subObjects[i].GetMeshes(Rhino.Geometry.MeshType.Preview); } - if (subMeshes.Length == 1) meshes[i] = subMeshes[0]; - else if (subMeshes.Length > 1) RhinoApp.WriteLine("This shouldn't have happened: An sub object created more than one mesh! RhinoDocGltfConverter.cs line:349"); + + if (subMeshes.Length == 1) + { + meshes[i] = subMeshes[0]; + } + else if (subMeshes.Length > 1) + { + RhinoApp.WriteLine("This shouldn't have happened: An sub object created more than one mesh! RhinoDocGltfConverter.cs line:349"); + } } List validMeshes = new List(); @@ -393,16 +419,6 @@ public bool MeshIsValidForExport(Rhino.Geometry.Mesh mesh) return true; } - private string GetDebugName(RhinoObject rhinoObject) - { - if (string.IsNullOrEmpty(rhinoObject.Name)) - { - return "(Unnamed)"; - } - - return rhinoObject.Name; - } - public List SanitizeRhinoObjects(IEnumerable rhinoObjects) { var rhinoObjectsRes = new List(); @@ -411,7 +427,7 @@ public List SanitizeRhinoObjects(IEnumerable rhin { if (!rhinoObject.IsMeshable(Rhino.Geometry.MeshType.Any)) { - RhinoApp.WriteLine("Skipping " + GetDebugName(rhinoObject) + ", object is not meshable. Object is a " + rhinoObject.ObjectType.ToString()); + RhinoApp.WriteLine("Skipping " + GetObjectName(rhinoObject) + ", object is not meshable. Object is a " + rhinoObject.ObjectType.ToString()); continue; } @@ -452,7 +468,7 @@ public List SanitizeRhinoObjects(IEnumerable rhin if (!item.rhinoObject.IsMeshable(Rhino.Geometry.MeshType.Any)) { - RhinoApp.WriteLine("Skipping " + GetDebugName(item.rhinoObject) + ", object is not meshable. Object is a " + item.rhinoObject.ObjectType.ToString()); + RhinoApp.WriteLine("Skipping " + GetObjectName(item.rhinoObject) + ", object is not meshable. Object is a " + item.rhinoObject.ObjectType.ToString()); continue; } @@ -487,17 +503,28 @@ public List SanitizeRhinoObjects(IEnumerable rhin private RenderMaterial[] GetRenderMaterials(RhinoObject rhinoObject) { var subObjects = rhinoObject.GetSubObjects(); - if (subObjects.Length == 0) subObjects = new RhinoObject[1] { rhinoObject }; + + if (subObjects.Length == 0) + { + subObjects = new RhinoObject[1] { rhinoObject }; + } + var mats = new RenderMaterial[subObjects.Length]; var components = rhinoObject.SubobjectMaterialComponents; + for (int i = 0; i < subObjects.Length; i++) { mats[i] = rhinoObject.RenderMaterial; + foreach (var component in components) { - if (component.Index == i) mats[i] = rhinoObject.GetRenderMaterial(component); + if (component.Index == i) + { + mats[i] = rhinoObject.GetRenderMaterial(component); + } } + if (mats[i] == null) { mats[i] = doc.Layers[rhinoObject.Attributes.LayerIndex].RenderMaterial; From d56752b8fdb32868d2b53df9a628cc6920d55fce Mon Sep 17 00:00:00 2001 From: Peter Krattenmacher Date: Sat, 4 Sep 2021 09:44:05 +0200 Subject: [PATCH 19/19] fix attempts. --- glTF-BinExporter/RhinoDocGltfConverter.cs | 49 +++++++++++++--------- glTF-BinExporter/RhinoMeshGltfConverter.cs | 2 +- 2 files changed, 30 insertions(+), 21 deletions(-) diff --git a/glTF-BinExporter/RhinoDocGltfConverter.cs b/glTF-BinExporter/RhinoDocGltfConverter.cs index 4afd150..81e15e0 100644 --- a/glTF-BinExporter/RhinoDocGltfConverter.cs +++ b/glTF-BinExporter/RhinoDocGltfConverter.cs @@ -345,37 +345,44 @@ public Rhino.Geometry.Mesh[] GetMeshes(RhinoObject rhinoObject) // Need to get a Mesh from the None-mesh object. Using the FastRenderMesh here. Could be made configurable. // First make sure the internal rhino mesh has been created - rhinoObject.CreateMeshes(Rhino.Geometry.MeshType.Preview, Rhino.Geometry.MeshingParameters.FastRenderMesh, true); + rhinoObject.CreateMeshes(MeshType.Preview, MeshingParameters.FastRenderMesh, true); // Then get the internal rhino meshes - //Rhino.Geometry.Mesh[] meshes = rhinoObject.GetMeshes(Rhino.Geometry.MeshType.Preview); + Rhino.Geometry.Mesh[] meshes;// = rhinoObject.GetMeshes(Rhino.Geometry.MeshType.Preview); + int count = 0; var subObjects = rhinoObject.GetSubObjects(); - if (subObjects.Length == 0) { - subObjects = new RhinoObject[1] { rhinoObject }; + meshes = rhinoObject.GetMeshes(MeshType.Preview); } - - Rhino.Geometry.Mesh[] meshes = new Rhino.Geometry.Mesh[subObjects.Length]; - - for (int i = 0; i < subObjects.Length; i++) + else { - var subMeshes = subObjects[i].GetMeshes(Rhino.Geometry.MeshType.Preview); + meshes = new Rhino.Geometry.Mesh[subObjects.Length]; + var jointMeshes = rhinoObject.GetMeshes(MeshType.Preview); + jointMeshes = jointMeshes[0].ExplodeAtUnweldedEdges(); - if (subMeshes.Length == 0) + for (int i = 0; i < subObjects.Length; i++) { - subObjects[i].CreateMeshes(Rhino.Geometry.MeshType.Preview, Rhino.Geometry.MeshingParameters.FastRenderMesh, true); - subMeshes = subObjects[i].GetMeshes(Rhino.Geometry.MeshType.Preview); - } + var subMeshes = subObjects[i].GetMeshes(MeshType.Preview); - if (subMeshes.Length == 1) - { - meshes[i] = subMeshes[0]; - } - else if (subMeshes.Length > 1) - { - RhinoApp.WriteLine("This shouldn't have happened: An sub object created more than one mesh! RhinoDocGltfConverter.cs line:349"); + if (subMeshes.Length == 0) + { + meshes[i] = jointMeshes[i]; + //subObjects[i].CreateMeshes(MeshType.Preview, MeshingParameters.FastRenderMesh, true); + //subMeshes = subObjects[i].GetMeshes(MeshType.Preview); + count++; + RhinoApp.WriteLine("Subobject didn't have a mesh! RhinoDocGltfConverter.cs line:370"); + } + + if (subMeshes.Length == 1) + { + meshes[i] = subMeshes[0]; + } + else if (subMeshes.Length > 1) + { + RhinoApp.WriteLine("This shouldn't have happened: An sub object created more than one mesh! RhinoDocGltfConverter.cs line:379"); + } } } @@ -445,6 +452,8 @@ public List SanitizeRhinoObjects(IEnumerable rhin Transform objectTransform; TextureMapping[] textureMappings = GetTextureMappings(rhinoObject, out objectTransform); + + var mats = GetRenderMaterials(rhinoObject); var meshes = GetMeshes(rhinoObject); diff --git a/glTF-BinExporter/RhinoMeshGltfConverter.cs b/glTF-BinExporter/RhinoMeshGltfConverter.cs index 4e856b8..d2db450 100644 --- a/glTF-BinExporter/RhinoMeshGltfConverter.cs +++ b/glTF-BinExporter/RhinoMeshGltfConverter.cs @@ -180,7 +180,7 @@ private void PreprocessMesh(Mesh rhinoMesh) primitive.Attributes.Add(Constants.TexCoord1AttributeTag, textureCoordinatesAccessorIdx); } } - else if(textureMappings.Length > 1 && options.UV0 != options.UV1) + else if(textureMappings.Length > 1 && textureMappings[1] !=null && options.UV0 != options.UV1) { rhinoMesh.SetTextureCoordinates(textureMappings[1], exportData.ObjectTransform, false); int newTextureCoordinatesAccessorIdx = GetTextureCoordinatesAccessor(rhinoMesh.TextureCoordinates);