diff --git a/Common_glTF_Exporter/Common_glTF_Exporter.projitems b/Common_glTF_Exporter/Common_glTF_Exporter.projitems
index 8005c04..386632e 100644
--- a/Common_glTF_Exporter/Common_glTF_Exporter.projitems
+++ b/Common_glTF_Exporter/Common_glTF_Exporter.projitems
@@ -9,24 +9,9 @@
Common_glTF_Exporter
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
@@ -54,9 +39,7 @@
-
-
diff --git a/Common_glTF_Exporter/Core/GLTFAccessor.cs b/Common_glTF_Exporter/Core/GLTFAccessor.cs
deleted file mode 100644
index ed37c9e..0000000
--- a/Common_glTF_Exporter/Core/GLTFAccessor.cs
+++ /dev/null
@@ -1,64 +0,0 @@
-namespace Common_glTF_Exporter.Core
-{
- using System.Collections.Generic;
- using Revit_glTF_Exporter;
-
- ///
- /// A reference to a subsection of a BufferView containing a particular data type
- /// https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#accessors.
- ///
- public class GLTFAccessor
- {
- public GLTFAccessor(int bufferView, int byteOffset, ComponentType componentType, int count, string type, List max, List min, string name)
- {
- this.bufferView = bufferView;
- this.byteOffset = byteOffset;
- this.componentType = componentType;
- this.count = count;
- this.type = type;
- this.max = max;
- this.min = min;
- this.name = name;
- }
-
- ///
- /// Gets or sets the index of the bufferView.
- ///
- public int bufferView { get; set; }
-
- ///
- /// Gets or sets the offset relative to the start of the bufferView in bytes.
- ///
- public int byteOffset { get; set; }
-
- ///
- /// Gets or sets the datatype of the components in the attribute.
- ///
- public ComponentType componentType { get; set; }
-
- ///
- /// Gets or sets the number of attributes referenced by this accessor.
- ///
- public int count { get; set; }
-
- ///
- /// Gets or sets the specifies if the attribute is a scala, vector, or matrix.
- ///
- public string type { get; set; }
-
- ///
- /// Gets or sets the maximum value of each component in this attribute.
- ///
- public List max { get; set; }
-
- ///
- /// Gets or sets the minimum value of each component in this attribute.
- ///
- public List min { get; set; }
-
- ///
- /// Gets or sets a user defined name for this accessor.
- ///
- public string name { get; set; }
- }
-}
diff --git a/Common_glTF_Exporter/Core/GLTFAttribute.cs b/Common_glTF_Exporter/Core/GLTFAttribute.cs
deleted file mode 100644
index b1c4a57..0000000
--- a/Common_glTF_Exporter/Core/GLTFAttribute.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-namespace Common_glTF_Exporter.Core
-{
- using Newtonsoft.Json;
- using System;
- using System.Collections.Generic;
- using System.Text;
-
- ///
- /// The list of accessors available to the renderer for a particular mesh
- /// https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#meshes.
- ///
- public class GLTFAttribute
- {
- ///
- /// Gets or sets the index of the accessor for position data.
- ///
- public int POSITION { get; set; }
-
- ///
- /// Gets or sets the index of the accessor for normal data.
- ///
- [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
- public int? NORMAL { get; set; }
-
- ///
- /// Gets or sets the index of the accessor for batchId data.
- ///
- [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
- public int? _BATCHID { get; set; }
-
- ///
- /// Gets or sets the index of the UV Coordinates of the material's textures.
- ///
- [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
- public int? TEXCOORD_0 { get; set; }
- }
-}
diff --git a/Common_glTF_Exporter/Core/GLTFBinaryData.cs b/Common_glTF_Exporter/Core/GLTFBinaryData.cs
deleted file mode 100644
index 7908002..0000000
--- a/Common_glTF_Exporter/Core/GLTFBinaryData.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-namespace Common_glTF_Exporter.Core
-{
- using System;
- using System.Collections.Generic;
- using System.Text;
-
- ///
- /// A binary data store serialized to a *.bin file
- /// https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#binary-data-storage.
- ///
- public class GLTFBinaryData
- {
- public List vertexBuffer { get; set; } = new List();
-
- public List normalBuffer { get; set; } = new List();
-
- public List indexBuffer { get; set; } = new List();
-
- public List batchIdBuffer { get; set; } = new List();
-
- public int vertexAccessorIndex { get; set; }
-
- public int normalsAccessorIndex { get; set; }
-
- public int indexAccessorIndex { get; set; }
-
- public int batchIdAccessorIndex { get; set; }
-
- public string name { get; set; }
-
- public List uvBuffer { get; set; } = new List();
- public int uvAccessorIndex { get; set; } = -1;
-
- public byte[] byteData { get; set; } = null;
- }
-}
diff --git a/Common_glTF_Exporter/Core/GLTFBuffer.cs b/Common_glTF_Exporter/Core/GLTFBuffer.cs
deleted file mode 100644
index a973d3a..0000000
--- a/Common_glTF_Exporter/Core/GLTFBuffer.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-namespace Common_glTF_Exporter.Core
-{
- using System;
- using System.Collections.Generic;
- using System.Text;
-
- ///
- /// A reference to the location and size of binary data
- /// https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#buffers-and-buffer-views.
- ///
- public class GLTFBuffer
- {
- ///
- /// Gets or sets the uri of the buffer.
- ///
- public string uri { get; set; }
-
- ///
- /// Gets or sets the total byte length of the buffer.
- ///
- public int byteLength { get; set; }
- }
-}
diff --git a/Common_glTF_Exporter/Core/GLTFBufferView.cs b/Common_glTF_Exporter/Core/GLTFBufferView.cs
deleted file mode 100644
index 11e3306..0000000
--- a/Common_glTF_Exporter/Core/GLTFBufferView.cs
+++ /dev/null
@@ -1,55 +0,0 @@
-namespace Common_glTF_Exporter.Core
-{
- using Newtonsoft.Json;
- using Revit_glTF_Exporter;
-
- ///
- /// A reference to a subsection of a buffer containing either vector or scalar data.
- /// https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#buffers-and-buffer-views
- ///
- public class GLTFBufferView
- {
- public GLTFBufferView(int buffer, int byteOffset, int byteLength, Targets target, string name)
- {
- this.buffer = buffer;
- this.byteOffset = byteOffset;
- this.byteLength = byteLength;
- this.target = target;
- this.name = name;
- }
-
- [JsonProperty("buffer")]
- public int buffer { get; set; }
-
- [JsonProperty("byteOffset")]
- public int byteOffset { get; set; }
-
- [JsonProperty("byteLength")]
- public int byteLength { get; set; }
-
- [JsonIgnore] // Ignore the raw enum field so we can customize serialization
- public Targets target { get; set; }
-
- [JsonProperty("target")]
- public int? TargetValue
- {
- get
- {
- if (target == Targets.ARRAY_BUFFER)
- return 34962;
- else if (target == Targets.ELEMENT_ARRAY_BUFFER)
- return 34963;
- else
- return null;
- }
- }
-
- public bool ShouldSerializeTargetValue()
- {
- return TargetValue != null;
- }
-
- [JsonProperty("name")]
- public string name { get; set; }
- }
-}
diff --git a/Common_glTF_Exporter/Core/GLTFExtras.cs b/Common_glTF_Exporter/Core/GLTFExtras.cs
deleted file mode 100644
index c5aa8ef..0000000
--- a/Common_glTF_Exporter/Core/GLTFExtras.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-namespace Common_glTF_Exporter.Core
-{
- using System.Collections.Generic;
- using Common_glTF_Exporter.Export;
- using Revit_glTF_Exporter;
-
- public class GLTFExtras
- {
- ///
- /// Gets or sets the Revit created UniqueId for this object.
- ///
- public string uniqueId { get; set; }
-
- public RevitGridParametersObject gridParameters { get; set; }
-
- public Dictionary parameters { get; set; }
-
- public long elementId { get; set; }
-
- public string elementCategory { get; set; }
- }
-}
diff --git a/Common_glTF_Exporter/Core/GLTFImage.cs b/Common_glTF_Exporter/Core/GLTFImage.cs
deleted file mode 100644
index e47bb30..0000000
--- a/Common_glTF_Exporter/Core/GLTFImage.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using Newtonsoft.Json;
-
-namespace Common_glTF_Exporter.Core
-{
- ///
- /// An image used by a texture
- /// https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#images
- ///
- public class GLTFImage
- {
- [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
- public string uri { get; set; }
-
- [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
- public int? bufferView { get; set; }
-
- [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
- public string mimeType { get; set; }
- }
-}
\ No newline at end of file
diff --git a/Common_glTF_Exporter/Core/GLTFMaterial.cs b/Common_glTF_Exporter/Core/GLTFMaterial.cs
deleted file mode 100644
index 842338b..0000000
--- a/Common_glTF_Exporter/Core/GLTFMaterial.cs
+++ /dev/null
@@ -1,45 +0,0 @@
-namespace Common_glTF_Exporter.Core
-{
- using System;
- using System.Collections.Generic;
- using System.Drawing;
- using System.Text;
- using Newtonsoft.Json;
- using Revit_glTF_Exporter;
-
- ///
- /// The glTF PBR Material format
- /// https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#materials.
- ///
- public class GLTFMaterial
- {
- public string alphaMode { get; set; }
-
- public float? alphaCutoff { get; set; }
-
- public string name { get; set; }
-
- public GLTFPBR pbrMetallicRoughness { get; set; }
-
- public bool doubleSided { get; set; }
-
- public GLTFTexture normalTexture { get; set; }
- public GLTFTexture occlusionTexture { get; set; }
- public GLTFTexture emissiveTexture { get; set; }
- public List emissiveFactor { get; set; }
-
- [JsonIgnore]
- public string EmbeddedTexturePath { get; set; } = null;
- [JsonIgnore]
- public double Fadevalue { get; set; } = 1;
-
- [JsonIgnore]
- public Autodesk.Revit.DB.Color TintColour { get; set; }
-
- [JsonIgnore]
- public Autodesk.Revit.DB.Color BaseColor { get; set; }
-
- [JsonIgnore]
- public string UniqueId { get; set; } = null;
- }
-}
diff --git a/Common_glTF_Exporter/Core/GLTFMesh.cs b/Common_glTF_Exporter/Core/GLTFMesh.cs
deleted file mode 100644
index ebc1238..0000000
--- a/Common_glTF_Exporter/Core/GLTFMesh.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-namespace Common_glTF_Exporter.Core
-{
- using System;
- using System.Collections.Generic;
- using System.Text;
- using Revit_glTF_Exporter;
-
- ///
- /// The array of primitives defining the mesh of an object
- /// https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#meshes.
- ///
- public class GLTFMesh
- {
- public List primitives { get; set; }
-
- public string name { get; set; }
- }
-}
diff --git a/Common_glTF_Exporter/Core/GLTFMeshPrimitive.cs b/Common_glTF_Exporter/Core/GLTFMeshPrimitive.cs
deleted file mode 100644
index f3eed35..0000000
--- a/Common_glTF_Exporter/Core/GLTFMeshPrimitive.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-namespace Common_glTF_Exporter.Core
-{
- using System;
- using System.Collections.Generic;
- using System.Text;
- using static Revit_glTF_Exporter.GLTF;
-
- ///
- /// Properties defining where the GPU should look to find the mesh and material data
- /// https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#meshes.
- ///
- public class GLTFMeshPrimitive
- {
- public GLTFAttribute attributes { get; set; } = new GLTFAttribute();
-
- public int indices { get; set; }
-
- public int? material { get; set; } = null;
-
- public int mode { get; set; } = 4; // 4 is triangles
- }
-}
diff --git a/Common_glTF_Exporter/Core/GLTFNode.cs b/Common_glTF_Exporter/Core/GLTFNode.cs
deleted file mode 100644
index d0d9d29..0000000
--- a/Common_glTF_Exporter/Core/GLTFNode.cs
+++ /dev/null
@@ -1,55 +0,0 @@
-namespace Common_glTF_Exporter.Core
-{
- using System;
- using System.Collections.Generic;
- using System.Text;
- using Autodesk.Revit.DB;
- using Revit_glTF_Exporter;
-
- ///
- /// The nodes defining individual (or nested) elements in the scene
- /// https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#nodes-and-hierarchy.
- ///
- public class GLTFNode
- {
- ///
- /// Gets or sets the user-defined name of this object.
- ///
- public string name { get; set; }
-
- ///
- /// Gets or sets the index of the mesh in this node.
- ///
- public int? mesh { get; set; } = null;
-
- ///
- /// Gets or sets a floating-point 4x4 transformation matrix stored in column major order.
- ///
- public List matrix { get; set; }
-
- ///
- /// Gets or sets the indices of this node's children.
- ///
- public List children { get; set; }
-
- ///
- /// Gets or sets the extras describing this node.
- ///
- public GLTFExtras extras { get; set; }
-
- ///
- /// Gets or sets rotation of the node.
- ///
- public List rotation { get; set; }
-
- ///
- /// Gets or sets translation of the node.
- ///
- public List translation { get; set; }
-
- ///
- /// Gets or sets scale of the node.
- ///
- public List scale { get; set; }
- }
-}
diff --git a/Common_glTF_Exporter/Core/GLTFScene.cs b/Common_glTF_Exporter/Core/GLTFScene.cs
deleted file mode 100644
index 1c30c67..0000000
--- a/Common_glTF_Exporter/Core/GLTFScene.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-namespace Common_glTF_Exporter.Core
-{
- using System.Collections.Generic;
-
- ///
- /// The scenes available to render
- /// https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#scenes.
- ///
- public class GLTFScene
- {
- public List nodes = new List();
- }
-}
diff --git a/Common_glTF_Exporter/Core/GLTFTextureInfo.cs b/Common_glTF_Exporter/Core/GLTFTextureInfo.cs
deleted file mode 100644
index daa9480..0000000
--- a/Common_glTF_Exporter/Core/GLTFTextureInfo.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-namespace Common_glTF_Exporter.Core
-{
- using Newtonsoft.Json;
- using System;
- using System.Collections.Generic;
-
- ///
- /// Texture information for a material property
- /// https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#texture-info
- ///
- public class GLTFTexture
- {
- public int source { get; set; }
- }
-
- public class GLTFTextureInfo
- {
- public int index { get; set; }
- public int texCoord { get; set; } = 0;
-
- [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
- public GLTFTextureExtensions extensions { get; set; }
- }
-
- public class GLTFTextureTransform
- {
- public float[] offset { get; set; } = new float[] { 0.0f, 0.0f };
- public float[] scale { get; set; } = new float[] { 1.0f, 1.0f };
- public float rotation { get; set; } = 0.0f;
- public int texCoord { get; set; } = 0;
- }
-
- public class GLTFTextureExtensions
- {
- [JsonProperty("KHR_texture_transform")]
- public GLTFTextureTransform TextureTransform { get; set; }
- }
-}
\ No newline at end of file
diff --git a/Common_glTF_Exporter/Core/GLTFVersion.cs b/Common_glTF_Exporter/Core/GLTFVersion.cs
deleted file mode 100644
index 192cc9d..0000000
--- a/Common_glTF_Exporter/Core/GLTFVersion.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-namespace Common_glTF_Exporter.Core
-{
- using Common_glTF_Exporter.Utils;
- using System;
- using System.Collections.Generic;
- using System.Text;
-
- ///
- /// Required glTF asset information
- /// https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#asset.
- ///
- public class GLTFVersion
- {
- public string version = "2.0";
- public string generator = string.Concat("e-verse custom generator ", SettingsConfig.currentVersion);
- public string copyright = "free tool created by e-verse";
- }
-}
diff --git a/Common_glTF_Exporter/Core/GlTFExportContext.cs b/Common_glTF_Exporter/Core/GlTFExportContext.cs
index 3cde758..731921e 100644
--- a/Common_glTF_Exporter/Core/GlTFExportContext.cs
+++ b/Common_glTF_Exporter/Core/GlTFExportContext.cs
@@ -1,16 +1,17 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using Autodesk.Revit.DB;
+using Autodesk.Revit.DB;
+using Common_glTF_Exporter.EportUtils;
using Common_glTF_Exporter.Export;
using Common_glTF_Exporter.Model;
using Common_glTF_Exporter.Transform;
using Common_glTF_Exporter.Utils;
using Common_glTF_Exporter.Windows.MainWindow;
+using glTF.Manipulator.GenericSchema;
+using glTF.Manipulator.Schema;
+using glTF.Manipulator.Utils;
using Revit_glTF_Exporter;
-using Common_glTF_Exporter.EportUtils;
-using System.Windows.Media.Media3D;
-using System.Windows.Controls;
+using System.Collections.Generic;
+using System.Linq;
+using Buffer = glTF.Manipulator.Schema.Buffer;
namespace Common_glTF_Exporter.Core
{
@@ -31,10 +32,8 @@ public class GLTFExportContext : IExportContext
private Document currentDocument;
private Autodesk.Revit.DB.View currentView;
- private GLTFNode currentNode;
private Element currentElement;
- private Face currentFace;
- private GLTFMaterial currentMaterial;
+ private BaseMaterial currentMaterial;
private Stack transformStack = new Stack();
///
@@ -52,20 +51,22 @@ public class GLTFExportContext : IExportContext
///
/// Reference to the rootNode to add children.
///
- private GLTFNode rootNode;
-
- public IndexedDictionary nodes = new IndexedDictionary();
-
- public IndexedDictionary materials = new IndexedDictionary();
- public List textures { get; } = new List();
- public List images { get; } = new List();
- public List scenes { get; } = new List();
- public IndexedDictionary meshes { get; } = new IndexedDictionary();
- public List buffers { get; } = new List();
- public List bufferViews { get; } = new List();
- public List accessors { get; } = new List();
+ private Node rootNode;
+
+ public IndexedDictionary nodes = new IndexedDictionary();
+
+ public IndexedDictionary materials = new IndexedDictionary();
+ public List textures { get; } = new List();
+ public List images { get; } = new List();
+ public List scenes { get; } = new List();
+ public IndexedDictionary meshes { get; } = new IndexedDictionary();
+ public List buffers { get; } = new List();
+ public List bufferViews { get; } = new List();
+ public List accessors { get; } = new List();
public List binaryFileData { get; } = new List();
+ GLTFBinaryData globalBuffer = new GLTFBinaryData();
+
private Autodesk.Revit.DB.Transform CurrentTransform
{
get
@@ -93,7 +94,7 @@ public bool Start()
transformStack.Push(Autodesk.Revit.DB.Transform.Identity);
// Creation Root Node
- rootNode = new GLTFNode();
+ rootNode = new Node();
rootNode.name = "rootNode";
rootNode.rotation = ModelRotation.Get(preferences.flipAxis);
rootNode.scale = ModelScale.Get(preferences);
@@ -104,7 +105,7 @@ public bool Start()
nodes.AddOrUpdateCurrent("rootNode", rootNode);
// Creation default scene
- GLTFScene defaultScene = new GLTFScene();
+ Scene defaultScene = new Scene();
defaultScene.nodes.Add(0);
scenes.Add(defaultScene);
@@ -112,7 +113,9 @@ public bool Start()
currentVertices = new IndexedDictionary();
currentMaterial = GLTFExportUtils.CreateDefaultGLTFMaterial(1, true);
- materials.AddOrUpdateCurrentMaterial(currentMaterial.UniqueId, currentMaterial, false);
+
+ materials.AddOrUpdateCurrentMaterial(currentMaterial.uuid, currentMaterial, false);
+
return true;
}
@@ -127,14 +130,27 @@ public void Finish()
return;
}
+ Buffer buffer = new Buffer();
+ buffer.uri = string.Concat(preferences.fileName, ".bin");
+
+ if (preferences.materials == MaterialsEnum.textures)
+ {
+ GLTFBinaryDataUtils.ExportImageBuffer(images, bufferViews, globalBuffer);
+ }
+
if (preferences.grids)
{
RevitGrids.Export(currentDocument, ref nodes, ref rootNode, preferences);
}
+ buffer.byteLength = globalBuffer.GetCurrentByteOffset();
+ buffers.Add(buffer);
+
if (bufferViews.Count != 0)
{
- FileExport.Run(preferences, bufferViews, buffers, binaryFileData,
+ ProgressBarWindow.ViewModel.Message = "Saving to File";
+
+ FileExport.Run(preferences, bufferViews, buffers, globalBuffer,
scenes, nodes, meshes, materials, accessors, textures, images);
Compression.Run(preferences, ProgressBarWindow.ViewModel);
}
@@ -174,7 +190,6 @@ public RenderNodeAction OnElementBegin(ElementId elementId)
}
}
- currentNode = GLTFNodeActions.CreateGLTFNodeFromElement(currentElement, preferences);
currentGeometry.Reset();
currentVertices.Reset();
@@ -182,8 +197,6 @@ public RenderNodeAction OnElementBegin(ElementId elementId)
return RenderNodeAction.Proceed;
}
- const char UNDERSCORE = '_';
-
///
/// Runs at the end of an element being processed, after all other calls for that element.
/// Here we compile all the "_current" variables (geometry and vertices) onto glTF buffers.
@@ -199,76 +212,11 @@ public void OnElementEnd(ElementId elementId)
return;
}
- nodes.AddOrUpdateCurrent(currentElement.UniqueId, currentNode);
- rootNode.children.Add(nodes.CurrentIndex);
-
- GLTFMesh newMesh = new GLTFMesh
- {
- name = currentElement.Name,
- primitives = new List()
- };
- meshes.AddOrUpdateCurrent(currentElement.UniqueId, newMesh);
- nodes.CurrentItem.mesh = meshes.CurrentIndex;
-
- // Convert _currentGeometry objects into glTFMeshPrimitives
- foreach (KeyValuePair kvp in currentGeometry.Dict)
- {
- string material_key = kvp.Key.Split(UNDERSCORE)[1];
- GLTFMaterial mat = materials.GetElement(material_key);
-
- GLTFBinaryData elementBinary = GLTFExportUtils.AddGeometryMeta(
- buffers,
- accessors,
- bufferViews,
- kvp.Value,
- kvp.Key,
-#if REVIT2024 || REVIT2025 || REVIT2026
- elementId.Value,
-#else
- elementId.IntegerValue,
-#endif
- preferences,
- mat,
- images,
- textures);
-
- binaryFileData.Add(elementBinary);
-
+ ProcessGeometry.ProcessNode(nodes, rootNode, meshes, preferences,
+ globalBuffer, bufferViews, accessors, materials, currentGeometry, currentElement);
- GLTFMeshPrimitive primitive = new GLTFMeshPrimitive();
-
- primitive.attributes.POSITION = elementBinary.vertexAccessorIndex;
-
- if (preferences.normals)
- {
- primitive.attributes.NORMAL = elementBinary.normalsAccessorIndex;
- }
-
- if (preferences.batchId)
- {
- primitive.attributes._BATCHID = elementBinary.batchIdAccessorIndex;
- }
-
- if (elementBinary.uvAccessorIndex != -1 &&
- preferences.materials == MaterialsEnum.textures &&
- mat.EmbeddedTexturePath != null)
- {
- primitive.attributes.TEXCOORD_0 = elementBinary.uvAccessorIndex;
- }
-
- primitive.indices = elementBinary.indexAccessorIndex;
-
- if (preferences.materials == MaterialsEnum.materials || preferences.materials == MaterialsEnum.textures)
- {
- if (materials.Contains(material_key))
- {
- primitive.material = materials.GetIndexFromUUID(material_key);
- }
- }
-
- meshes.CurrentItem.primitives.Add(primitive);
- meshes.CurrentItem.name = currentElement.Name;
- }
+ currentGeometry.Reset();
+ currentVertices.Reset();
}
///
@@ -280,23 +228,14 @@ public void OnElementEnd(ElementId elementId)
public void OnMaterial(MaterialNode node)
{
if (preferences.materials == MaterialsEnum.materials || preferences.materials == MaterialsEnum.textures)
- {
+ {
if (node.MaterialId == ElementId.InvalidElementId)
{
- currentMaterial = GLTFExportUtils.GetGLTFMaterial(materials, node.Transparency, false);
+ currentMaterial = GLTFExportUtils.GetGLTFMaterial(materials);
}
else
{
- string materialId = node.MaterialId.ToString();
- if (materials.Contains(materialId))
- {
- currentMaterial = materials.GetElement(materialId);
- }
- else
- {
- currentMaterial = RevitMaterials.Export(node, preferences, currentDocument);
- }
- materials.AddOrUpdateCurrentMaterial(materialId, currentMaterial, false);
+ currentMaterial = RevitMaterials.ProcessMaterial(node, preferences, currentDocument, materials, textures, images);
}
}
}
@@ -332,10 +271,14 @@ public void OnPolymesh(PolymeshTopology polymesh)
new PointIntObject(vertex), geomItem.Vertices);
geomItem.Faces.Add(vertexIndex);
- if (preferences.materials == MaterialsEnum.textures && currentMaterial?.EmbeddedTexturePath != null)
+ if (preferences.materials == MaterialsEnum.textures && currentMaterial.hasTexture)
{
UV uv = uvs[index];
- UV flippedUV = new UV(uv.U, 1.0 - uv.V);
+ GltfUV flippedUV = new GltfUV
+ {
+ U = (float)uv.U,
+ V = (float)(1.0 - uv.V)
+ };
geomItem.Uvs.Add(flippedUV);
}
}
@@ -440,7 +383,7 @@ public void OnRPC(RPCNode node)
if (preferences.materials == MaterialsEnum.materials || preferences.materials == MaterialsEnum.textures)
{
currentMaterial = MaterialUtils.GetGltfMeshMaterial(currentDocument, preferences, mesh, materials, true);
- materials.AddOrUpdateCurrentMaterial(currentMaterial.UniqueId, currentMaterial, true);
+ materials.AddOrUpdateCurrentMaterial(currentMaterial.name, currentMaterial, true);
}
GLTFExportUtils.AddOrUpdateCurrentItem(currentElement, currentGeometry, currentVertices, currentMaterial);
@@ -486,12 +429,10 @@ public void OnLight(LightNode node)
public RenderNodeAction OnFaceBegin(FaceNode node)
{
- currentFace = node.GetFace();
return RenderNodeAction.Proceed;
}
public void OnFaceEnd(FaceNode node)
{
- currentFace = null;
}
}
}
\ No newline at end of file
diff --git a/Common_glTF_Exporter/Core/IndexedDictionary.cs b/Common_glTF_Exporter/Core/IndexedDictionary.cs
deleted file mode 100644
index 3230c82..0000000
--- a/Common_glTF_Exporter/Core/IndexedDictionary.cs
+++ /dev/null
@@ -1,163 +0,0 @@
-namespace Revit_glTF_Exporter
-{
- using System;
- using System.Collections.Generic;
- using Common_glTF_Exporter.Core;
-
- ///
- /// Container for holding a strict set of items
- /// that is also addressable by a unique ID.
- ///
- /// The type of item contained.
- public class IndexedDictionary
- {
- private Dictionary dict = new Dictionary();
-
- ///
- /// Gets all the generic elements inside the IndexedDictionary.
- ///
- public List List { get; } = new List();
-
- ///
- /// Gets the current key from actual element.
- ///
- public string CurrentKey { get; private set; }
-
- ///
- /// Temp output used in 'this.Dict'
- ///
- Dictionary output = new Dictionary();
-
- ///
- /// Gets the dictionary.
- ///
- public Dictionary Dict
- {
- get
- {
- output.Clear();
- foreach (var kvp in this.dict)
- {
- output.Add(kvp.Key, this.List[kvp.Value]);
- }
-
- return output;
- }
- }
-
- ///
- /// Gets the most recently accessed item (not effected by GetElement()).
- ///
- public T CurrentItem
- {
- get { return this.List[this.dict[this.CurrentKey]]; }
- }
-
- ///
- /// Gets the index of the most recently accessed item (not effected by GetElement()).
- ///
- public int CurrentIndex
- {
- get { return this.dict[this.CurrentKey]; }
- }
-
- ///
- /// Add a new item to the list, if it already exists then the current item will be set to this item.
- ///
- /// Unique identifier for the item.
- /// The item to add.
- /// true if item did not already exist.
- public bool AddOrUpdateCurrent(string uuid, T elem)
- {
- if (!this.dict.ContainsKey(uuid))
- {
- this.List.Add(elem);
- this.dict.Add(uuid, this.List.Count - 1);
- this.CurrentKey = uuid;
- return true;
- }
-
- this.CurrentKey = uuid;
-
- return false;
- }
-
- ///
- /// Add a new gltfMaterial to the list, if it already exists then the current item will be set to this item.
- ///
- /// Unique identifier for the item.
- /// The item to add.
- /// Identify if the material is double sided.
- /// true if item did not already exist.
- public bool AddOrUpdateCurrentMaterial(string uuid, T elem, bool doubleSided)
- {
- if (!this.dict.ContainsKey(uuid))
- {
- this.List.Add(elem);
- this.dict.Add(uuid, this.List.Count - 1);
- this.CurrentKey = uuid;
- return true;
- }
-
- this.CurrentKey = uuid;
-
- if (elem is GLTFMaterial)
- {
- var mat = this.GetElement(uuid) as GLTFMaterial;
- mat.doubleSided = doubleSided;
- }
-
- return false;
- }
-
- ///
- /// Check if the container already has an item with this key.
- ///
- /// Unique identifier for the item.
- /// Returns TRUE if the dictionary contains the given element, otherwise, returns FALSE.
- public bool Contains(string uuid)
- {
- return this.dict.ContainsKey(uuid);
- }
-
- ///
- /// Returns the index for an item given it's unique identifier.
- ///
- /// Unique identifier for the item.
- /// index of item or -1.
- public int GetIndexFromUUID(string uuid)
- {
- try
- {
- return this.dict[uuid];
- }
- catch (KeyNotFoundException)
- {
- throw new Exception("Specified item could not be found.");
- }
- catch (Exception ex)
- {
- throw new Exception($"Error getting the specified item {ex.Message}");
- }
- }
-
- ///
- /// Returns an item given it's unique identifier.
- ///
- /// Unique identifier for the item.
- /// Element.
- public T GetElement(string uuid)
- {
- int index = this.GetIndexFromUUID(uuid);
- return this.List[index];
- }
-
- public void Reset()
- {
- this.dict.Clear();
- this.List.Clear();
- this.Dict.Clear();
- this.CurrentKey = string.Empty;
- }
- }
-}
diff --git a/Common_glTF_Exporter/Core/ProcessGeometry.cs b/Common_glTF_Exporter/Core/ProcessGeometry.cs
new file mode 100644
index 0000000..fe108a9
--- /dev/null
+++ b/Common_glTF_Exporter/Core/ProcessGeometry.cs
@@ -0,0 +1,106 @@
+using Autodesk.Revit.DB;
+using Common_glTF_Exporter.Model;
+using Common_glTF_Exporter.Utils;
+using Common_glTF_Exporter.Windows.MainWindow;
+using glTF.Manipulator.GenericSchema;
+using glTF.Manipulator.Schema;
+using glTF.Manipulator.Utils;
+using Revit_glTF_Exporter;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Windows.Forms;
+using System.Xml.Linq;
+
+namespace Common_glTF_Exporter.Core
+{
+ public static class ProcessGeometry
+ {
+ public static void ProcessNode(IndexedDictionary nodes, Node rootNode, IndexedDictionary meshes,
+ Preferences preferences, GLTFBinaryData globalBuffer, List bufferViews, List accessors, IndexedDictionary materials,
+ IndexedDictionary dataObject, Element currentElement)
+ {
+
+ Extras extras = new Extras();
+
+ if (preferences.properties)
+ {
+ var parameters = Util.GetElementParameters(currentElement, true);
+ parameters["UniqueId"] = currentElement.UniqueId;
+
+ if (currentElement.Category != null)
+ parameters["Category"] = currentElement.Category.Name;
+
+ extras.parameters = parameters;
+ }
+
+ Node newNode = new Node()
+ {
+ name = Util.ElementDescription(currentElement),
+ extras = extras
+ };
+
+ long elmId;
+
+ #if REVIT2024 || REVIT2025 || REVIT2026
+ elmId = currentElement.Id.Value;
+ #else
+ elmId = currentElement.Id.IntegerValue;
+ #endif
+
+ nodes.AddOrUpdateCurrent(currentElement.UniqueId, newNode);
+ rootNode.children.Add(nodes.CurrentIndex);
+
+ glTF.Manipulator.Schema.Mesh newMesh = new glTF.Manipulator.Schema.Mesh
+ {
+ name = currentElement.Name,
+ primitives = new List()
+ };
+
+ meshes.AddOrUpdateCurrent(currentElement.UniqueId, newMesh);
+ nodes.CurrentItem.mesh = meshes.CurrentIndex;
+
+ foreach (KeyValuePair kvp in dataObject.Dict)
+ {
+ MeshPrimitive primitive = new MeshPrimitive();
+ GLTFBinaryData gLTFBinaryDataElement = globalBuffer;
+
+ if (preferences.materials == MaterialsEnum.textures)
+ {
+ GLTFBinaryDataUtils.ExportUVs(kvp.Value, gLTFBinaryDataElement, bufferViews, accessors, primitive);
+ }
+
+ GLTFBinaryDataUtils.ExportVertices(kvp.Value, gLTFBinaryDataElement, bufferViews, accessors, primitive);
+
+ if (preferences.normals)
+ {
+ GLTFBinaryDataUtils.ExportNormals(kvp.Value, gLTFBinaryDataElement, bufferViews, accessors, primitive);
+ }
+
+ if (preferences.batchId)
+ {
+ GLTFBinaryDataUtils.ExportBatchId(elmId, kvp.Value, gLTFBinaryDataElement, bufferViews, accessors, primitive);
+ }
+
+ int indexAcessor = GLTFBinaryDataUtils.ExportFaces(kvp.Value, gLTFBinaryDataElement, bufferViews, accessors);
+
+ primitive.indices = indexAcessor;
+
+ if (preferences.materials != MaterialsEnum.nonematerials)
+ {
+ primitive.material = materials.GetIndexFromUUID(kvp.Value.MaterialInfo.uuid);
+ }
+
+ meshes.CurrentItem.primitives.Add(primitive);
+ meshes.CurrentItem.name = currentElement.Name;
+
+ var g = kvp.Value;
+ g.Vertices.Clear();
+ g.Normals.Clear();
+ g.Uvs.Clear();
+ g.Faces.Clear();
+ }
+ }
+ }
+}
diff --git a/Common_glTF_Exporter/Core/glTF.cs b/Common_glTF_Exporter/Core/glTF.cs
deleted file mode 100644
index 9b04486..0000000
--- a/Common_glTF_Exporter/Core/glTF.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-namespace Revit_glTF_Exporter
-{
- using System.Collections.Generic;
- using Common_glTF_Exporter.Core;
-
- ///
- /// Magic numbers to differentiate scalar and vector array buffers
- /// https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#buffers-and-buffer-views.
- ///
- public enum Targets
- {
- NONE = 0,
- ARRAY_BUFFER = 34962, // signals vertex data
- ELEMENT_ARRAY_BUFFER = 34963, // signals index or face data
- }
-
- ///
- /// Magic numbers to differentiate array buffer component types
- /// https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#accessor-element-size.
- ///
- public enum ComponentType
- {
- BYTE = 5120,
- UNSIGNED_BYTE = 5121,
- SHORT = 5122,
- UNSIGNED_SHORT = 5123,
- UNSIGNED_INT = 5125,
- FLOAT = 5126,
- }
-
- ///
- /// The json serializable glTF file format
- /// https://github.com/KhronosGroup/glTF/tree/master/specification/2.0.
- ///
- public struct GLTF
- {
- public GLTFVersion asset;
- public List extensionsUsed;
- public List scenes;
- public List nodes;
- public List meshes;
- public List buffers;
- public List bufferViews;
- public List accessors;
- public List materials;
- public List textures;
- public List images;
- }
-}
diff --git a/Common_glTF_Exporter/Core/glTFPBR.cs b/Common_glTF_Exporter/Core/glTFPBR.cs
deleted file mode 100644
index d7606e9..0000000
--- a/Common_glTF_Exporter/Core/glTFPBR.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-namespace Common_glTF_Exporter.Core
-{
- using System.Collections.Generic;
-
- public class GLTFPBR
- {
- public List baseColorFactor { get; set; }
-
- public float metallicFactor { get; set; }
-
- public float roughnessFactor { get; set; }
-
- // Texture properties
- public GLTFTextureInfo baseColorTexture { get; set; }
- public GLTFTexture metallicRoughnessTexture { get; set; }
- }
-}
diff --git a/Common_glTF_Exporter/EportUtils/ElementValidations.cs b/Common_glTF_Exporter/EportUtils/ElementValidations.cs
index b12dbe8..15e2b4a 100644
--- a/Common_glTF_Exporter/EportUtils/ElementValidations.cs
+++ b/Common_glTF_Exporter/EportUtils/ElementValidations.cs
@@ -1,24 +1,26 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Linq;
-using Autodesk.Revit.DB;
+using Autodesk.Revit.DB;
+using Common_glTF_Exporter.Core;
+using Common_glTF_Exporter.EportUtils;
using Common_glTF_Exporter.Export;
using Common_glTF_Exporter.Model;
using Common_glTF_Exporter.Transform;
using Common_glTF_Exporter.Utils;
using Common_glTF_Exporter.Windows.MainWindow;
+using glTF.Manipulator.Schema;
+using glTF.Manipulator.Utils;
using Revit_glTF_Exporter;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
using Transform = Autodesk.Revit.DB.Transform;
-using Common_glTF_Exporter.EportUtils;
-using Common_glTF_Exporter.Core;
namespace Common_glTF_Exporter.EportUtils
{
public static class ElementValidations
{
public static bool ShouldSkipElement(Element currentElement, Autodesk.Revit.DB.View currentView,
- Document currentDocument, Preferences preferences, IndexedDictionary nodes)
+ Document currentDocument, Preferences preferences, IndexedDictionary nodes)
{
if (currentElement == null)
{
diff --git a/Common_glTF_Exporter/EportUtils/GLTFNodeActions.cs b/Common_glTF_Exporter/EportUtils/GLTFNodeActions.cs
deleted file mode 100644
index 28f2586..0000000
--- a/Common_glTF_Exporter/EportUtils/GLTFNodeActions.cs
+++ /dev/null
@@ -1,45 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-using Autodesk.Revit.DB;
-using Revit_glTF_Exporter;
-using Common_glTF_Exporter.Core;
-using Common_glTF_Exporter.Windows.MainWindow;
-
-namespace Common_glTF_Exporter.EportUtils
-{
- public static class GLTFNodeActions
- {
- public static GLTFNode CreateGLTFNodeFromElement(Element currentElement, Preferences preferences)
- {
- // create a new node for the element
- GLTFNode newNode = new GLTFNode();
- newNode.name = Util.ElementDescription(currentElement);
-
- if (preferences.properties)
- {
- // get the extras for this element
- GLTFExtras extras = new GLTFExtras
- {
- uniqueId = currentElement.UniqueId,
- parameters = Util.GetElementParameters(currentElement, true)
- };
-
- if (currentElement.Category != null)
- {
- extras.elementCategory = currentElement.Category.Name;
- }
-
-#if REVIT2024 || REVIT2025 || REVIT2026
- extras.elementId = currentElement.Id.Value;
-#else
- extras.elementId = currentElement.Id.IntegerValue;
-#endif
-
- newNode.extras = extras;
- }
-
- return newNode;
- }
- }
-}
diff --git a/Common_glTF_Exporter/Export/BinFile.cs b/Common_glTF_Exporter/Export/BinFile.cs
index 9c242a8..904d89c 100644
--- a/Common_glTF_Exporter/Export/BinFile.cs
+++ b/Common_glTF_Exporter/Export/BinFile.cs
@@ -1,74 +1,21 @@
-namespace Common_glTF_Exporter.Export
-{
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Text;
- using Common_glTF_Exporter.Core;
- using Common_glTF_Exporter.Windows.MainWindow;
+using System.IO;
+using glTF.Manipulator.GenericSchema;
- public static class BinFile
+public static class BinFile
+{
+ ///
+ /// Create a new .bin file using the optimized GLTFBinaryData.
+ ///
+ public static void Create(string filename, GLTFBinaryData globalBuffer)
{
- ///
- /// Create a new .bin file.
- ///
- /// .bin file name.
- /// binary file data.
- /// export normals.
- /// export BatchId.
- public static void Create(string filename, List binaryFileData,
- Preferences preferences)
- {
- using (FileStream f = File.Create(filename))
- using (var writer = new BinaryWriter(new BufferedStream(f), Encoding.UTF8))
- {
- foreach (var bin in binaryFileData)
- {
- for (int i = 0; i < bin.vertexBuffer.Count; i++)
- {
- writer.Write((float)bin.vertexBuffer[i]);
- }
-
- if (preferences.normals)
- {
- for (int i = 0; i < bin.normalBuffer.Count; i++)
- {
- writer.Write((float)bin.normalBuffer[i]);
- }
- }
-
- if (preferences.materials == MaterialsEnum.textures)
- {
- if (bin.byteData != null)
- {
- writer.Write((byte[])bin.byteData);
- }
+ // Obtiene los bytes finales del MemoryStream
+ byte[] data = globalBuffer.ToArray();
- if (bin.uvBuffer != null && bin.uvBuffer.Count > 0)
- {
- for (int i = 0; i < bin.uvBuffer.Count; i++)
- {
- writer.Write((float)bin.uvBuffer[i]);
- }
- }
- }
-
- if (preferences.batchId)
- {
- for (int i = 0; i < bin.batchIdBuffer.Count; i++)
- {
- writer.Write((float)bin.batchIdBuffer[i]);
- }
- }
-
- for (int i = 0; i < bin.indexBuffer.Count; i++)
- {
- writer.Write((int)bin.indexBuffer[i]);
- }
- }
-
- writer.Flush();
- }
+ using (FileStream f = File.Create(filename))
+ using (var writer = new BinaryWriter(new BufferedStream(f)))
+ {
+ writer.Write(data);
+ writer.Flush();
}
}
}
diff --git a/Common_glTF_Exporter/Export/BufferConfig.cs b/Common_glTF_Exporter/Export/BufferConfig.cs
index 403d412..9680694 100644
--- a/Common_glTF_Exporter/Export/BufferConfig.cs
+++ b/Common_glTF_Exporter/Export/BufferConfig.cs
@@ -1,8 +1,9 @@
using System;
using System.Collections.Generic;
-using System.Text;
using Common_glTF_Exporter.Core;
using Common_glTF_Exporter.Windows.MainWindow;
+using glTF.Manipulator.Schema;
+using Buffer = glTF.Manipulator.Schema.Buffer;
namespace Common_glTF_Exporter.Export
{
@@ -10,7 +11,7 @@ public static class BufferConfig
{
const string BIN = ".bin";
- public static void Run(List bufferViews, List buffers,
+ public static void Run(List bufferViews, List buffers,
Preferences preferences)
{
int bytePosition = 0;
@@ -32,7 +33,7 @@ public static void Run(List bufferViews, List buffer
}
}
- GLTFBuffer buffer = new GLTFBuffer();
+ Buffer buffer = new Buffer();
if (preferences.format == FormatEnum.gltf)
{
diff --git a/Common_glTF_Exporter/Export/Draco.cs b/Common_glTF_Exporter/Export/Draco.cs
index acebdd9..e3a855e 100644
--- a/Common_glTF_Exporter/Export/Draco.cs
+++ b/Common_glTF_Exporter/Export/Draco.cs
@@ -1,14 +1,444 @@
-using System;
+using Common_glTF_Exporter.Model;
+using Common_glTF_Exporter.Windows.MainWindow;
+using dracowrapper;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
-using System.Windows;
-using Common_glTF_Exporter.Model;
-using Common_glTF_Exporter.Windows.MainWindow;
-using dracowrapper;
namespace Common_glTF_Exporter.Export
{
+ internal sealed class GlbData
+ {
+ public string Json;
+ public byte[] Bin;
+
+ public GlbData(string json, byte[] bin)
+ {
+ Json = json;
+ Bin = bin ?? new byte[0];
+ }
+ }
+
+ internal static class GltfExtrasPatcher
+ {
+ private static JToken DeepClone(JToken token)
+ {
+ if (token == null) return null;
+ return token.DeepClone();
+ }
+
+ public static void PatchExtras(string originalPath, string tempPath)
+ {
+ if (string.IsNullOrEmpty(originalPath) || string.IsNullOrEmpty(tempPath))
+ throw new ArgumentNullException();
+
+ string ext = (Path.GetExtension(originalPath) ?? "").ToLowerInvariant();
+ if (ext == ".gltf")
+ {
+ PatchExtrasGltf(originalPath, tempPath);
+ }
+ else if (ext == ".glb")
+ {
+ PatchExtrasGlb(originalPath, tempPath);
+ }
+ }
+
+ private static void PatchExtrasGltf(string originalGltf, string tempGltf)
+ {
+ JObject src = JObject.Parse(File.ReadAllText(originalGltf));
+ JObject dst = JObject.Parse(File.ReadAllText(tempGltf));
+
+ PatchArrayByIndex(src, dst, "nodes", PatchNodeLike);
+
+ MergeExtensionsUsedAndRequired(src, dst);
+
+ string baseDir = Path.GetDirectoryName(tempGltf);
+ string tempBinFileName = Path.GetFileName(tempGltf).Replace(".gltf", ".bin");
+
+ byte[] binBytes = null;
+ InlineExternalImagesIntoBin(dst, baseDir, tempBinFileName, ref binBytes, false, true);
+
+ if (binBytes != null)
+ {
+ string binPath = Path.Combine(baseDir, tempBinFileName);
+ File.WriteAllBytes(binPath, binBytes);
+ }
+
+ string jsonOut = dst.ToString(Formatting.None);
+ File.WriteAllText(tempGltf, jsonOut);
+ }
+
+ private static void PatchExtrasGlb(string originalGlb, string tempGlb)
+ {
+ GlbData srcGlb = ReadGlb(originalGlb);
+ GlbData dstGlb = ReadGlb(tempGlb);
+
+ JObject src = JObject.Parse(srcGlb.Json);
+ JObject dst = JObject.Parse(dstGlb.Json);
+
+ PatchArrayByIndex(src, dst, "nodes", PatchNodeLike);
+
+ MergeExtensionsUsedAndRequired(src, dst);
+
+ byte[] glbBin = dstGlb.Bin;
+ string baseDir = Path.GetDirectoryName(tempGlb);
+ InlineExternalImagesIntoBin(dst, baseDir, null, ref glbBin, true, true);
+
+ string newJson = dst.ToString(Formatting.None);
+ WriteGlb(tempGlb, newJson, glbBin);
+ }
+
+ private static void PatchNodeLike(JObject srcNode, JObject dstNode)
+ {
+ CopyExtras(srcNode, dstNode);
+ CopyUnknownExtensions(srcNode, dstNode, new[] { "KHR_draco_mesh_compression" });
+ }
+
+ private static void PatchArrayByIndex(JObject src, JObject dst, string name, Action patchItem)
+ {
+ JArray sa = src[name] as JArray;
+ JArray da = dst[name] as JArray;
+
+ if (sa == null || da == null) return;
+
+ int count = Math.Min(sa.Count, da.Count);
+ for (int i = 0; i < count; i++)
+ {
+ JObject sItem = sa[i] as JObject;
+ JObject dItem = da[i] as JObject;
+ if (sItem == null || dItem == null) continue;
+
+ patchItem(sItem, dItem);
+ }
+ }
+
+ private static void CopyExtras(JObject src, JObject dst)
+ {
+ JToken extras = src["extras"];
+ if (extras != null)
+ {
+ dst["extras"] = DeepClone(extras);
+ }
+ }
+
+ private static void CopyUnknownExtensions(JObject src, JObject dst, IEnumerable keepKnown)
+ {
+ JObject sExt = src["extensions"] as JObject;
+ if (sExt == null) return;
+
+ JObject dExt = dst["extensions"] as JObject;
+ if (dExt == null) dExt = new JObject();
+
+ HashSet known = new HashSet(keepKnown, StringComparer.Ordinal);
+
+ foreach (var kvp in sExt)
+ {
+ string name = kvp.Key;
+ JToken value = kvp.Value;
+ if (value == null) continue;
+
+ if (known.Contains(name) && dExt.ContainsKey(name)) continue;
+
+ dExt[name] = DeepClone(value);
+ }
+
+ if (dExt.Count > 0)
+ dst["extensions"] = dExt;
+ }
+
+ private static void MergeExtensionsUsedAndRequired(JObject src, JObject dst)
+ {
+ MergeTokenArray(src, dst, "extensionsUsed");
+ MergeTokenArray(src, dst, "extensionsRequired");
+
+ EnsureExtInArray(dst, "extensionsUsed", "KHR_draco_mesh_compression");
+ }
+
+ private static void MergeTokenArray(JObject src, JObject dst, string prop)
+ {
+ JArray srcArr = src[prop] as JArray;
+
+ if (srcArr == null || srcArr.Count == 0)
+ return;
+
+ JArray dstArr = dst[prop] as JArray;
+ if (dstArr == null)
+ {
+ dstArr = new JArray();
+ dst[prop] = dstArr;
+ }
+
+ HashSet existing = new HashSet(StringComparer.Ordinal);
+ foreach (JToken t in dstArr)
+ {
+ if (t == null) continue;
+ existing.Add((string)t);
+ }
+
+ foreach (JToken t in srcArr)
+ {
+ if (t == null) continue;
+ string name = (string)t;
+ if (!existing.Contains(name))
+ {
+ dstArr.Add(name);
+ existing.Add(name);
+ }
+ }
+ }
+
+ private static void EnsureExtInArray(JObject dst, string arrayName, string ext)
+ {
+ JArray arr = dst[arrayName] as JArray;
+ if (arr == null)
+ {
+ arr = new JArray();
+ dst[arrayName] = arr;
+ }
+
+ foreach (JToken t in arr)
+ {
+ if (t == null) continue;
+ if (string.Equals((string)t, ext, StringComparison.Ordinal))
+ return;
+ }
+
+ arr.Add(ext);
+ }
+
+ private static void InlineExternalImagesIntoBin(
+ JObject model,
+ string baseDir,
+ string desiredBinFileName,
+ ref byte[] binBytes,
+ bool isGlb,
+ bool removeExternalImageFiles)
+ {
+ JArray buffers = model["buffers"] as JArray;
+ if (buffers == null)
+ {
+ buffers = new JArray();
+ model["buffers"] = buffers;
+ }
+ if (buffers.Count == 0)
+ {
+ JObject bufObj = new JObject();
+ bufObj["byteLength"] = 0;
+ buffers.Add(bufObj);
+ }
+
+ JArray bufferViews = model["bufferViews"] as JArray;
+ if (bufferViews == null)
+ {
+ bufferViews = new JArray();
+ model["bufferViews"] = bufferViews;
+ }
+
+ JObject buf0 = buffers[0] as JObject;
+
+ if (!isGlb)
+ {
+ if (string.IsNullOrEmpty(desiredBinFileName))
+ desiredBinFileName = "sceneTemp.bin";
+
+ buf0["uri"] = desiredBinFileName;
+
+ string desiredBinPath = Path.Combine(baseDir, desiredBinFileName);
+ if ((binBytes == null || binBytes.Length == 0) && File.Exists(desiredBinPath))
+ {
+ binBytes = File.ReadAllBytes(desiredBinPath);
+ }
+ }
+
+ int appendOffset = (binBytes != null) ? binBytes.Length : 0;
+
+ JArray images = model["images"] as JArray;
+ HashSet consumedFiles = new HashSet(StringComparer.OrdinalIgnoreCase);
+
+ if (images != null)
+ {
+ for (int i = 0; i < images.Count; i++)
+ {
+ JObject img = images[i] as JObject;
+ if (img == null) continue;
+
+ if (img["bufferView"] != null) continue;
+
+ JToken uriNode = img["uri"];
+ string uri = (uriNode != null) ? (string)uriNode : null;
+ if (string.IsNullOrEmpty(uri)) continue;
+ if (uri.StartsWith("data:", StringComparison.OrdinalIgnoreCase)) continue;
+
+ string imgPath = Path.Combine(baseDir, uri);
+ if (!File.Exists(imgPath)) continue;
+
+ byte[] imgBytes = File.ReadAllBytes(imgPath);
+ string mime = MimeFromExtension(Path.GetExtension(uri));
+
+ int thisOffset = appendOffset;
+ binBytes = AppendBytes(binBytes, imgBytes, true, 0x00);
+ int thisLength = imgBytes.Length;
+ appendOffset = binBytes.Length;
+
+ int bvIndex = bufferViews.Count;
+ JObject bv = new JObject();
+ bv["buffer"] = 0;
+ bv["byteOffset"] = thisOffset;
+ bv["byteLength"] = thisLength;
+ bufferViews.Add(bv);
+
+ img.Remove("uri");
+ img["bufferView"] = bvIndex;
+
+ if (!string.IsNullOrEmpty(mime))
+ img["mimeType"] = mime;
+
+ if (removeExternalImageFiles)
+ consumedFiles.Add(imgPath);
+ }
+ }
+
+ buf0["byteLength"] = binBytes != null ? binBytes.Length : 0;
+
+ if (removeExternalImageFiles && consumedFiles.Count > 0)
+ {
+ foreach (string p in consumedFiles)
+ {
+ try
+ {
+ if (File.Exists(p)) File.Delete(p);
+ }
+ catch { }
+ }
+ }
+ }
+
+ private static string MimeFromExtension(string ext)
+ {
+ if (ext == null) ext = "";
+ ext = ext.ToLowerInvariant();
+
+ if (ext == ".png") return "image/png";
+ if (ext == ".jpg" || ext == ".jpeg") return "image/jpeg";
+ if (ext == ".ktx2") return "image/ktx2";
+ return null;
+ }
+
+ private static byte[] AppendBytes(byte[] bin, byte[] add, bool padTo4, byte padByte)
+ {
+ if (bin == null) bin = new byte[0];
+ if (add == null) add = new byte[0];
+
+ int oldLen = bin.Length;
+ int newLen = oldLen + add.Length;
+
+ byte[] outArr = new byte[newLen];
+ Buffer.BlockCopy(bin, 0, outArr, 0, oldLen);
+ Buffer.BlockCopy(add, 0, outArr, oldLen, add.Length);
+
+ if (padTo4)
+ {
+ int mod = outArr.Length % 4;
+ if (mod != 0)
+ {
+ int pad = 4 - mod;
+ byte[] padded = new byte[outArr.Length + pad];
+ Buffer.BlockCopy(outArr, 0, padded, 0, outArr.Length);
+ for (int i = 0; i < pad; i++)
+ padded[outArr.Length + i] = padByte;
+ return padded;
+ }
+ }
+
+ return outArr;
+ }
+
+ private static GlbData ReadGlb(string path)
+ {
+ using (FileStream fs = File.OpenRead(path))
+ using (BinaryReader br = new BinaryReader(fs))
+ {
+ uint magic = br.ReadUInt32();
+ uint version = br.ReadUInt32();
+ uint length = br.ReadUInt32();
+
+ uint chunkLen0 = br.ReadUInt32();
+ uint chunkType0 = br.ReadUInt32();
+ byte[] jsonBytes = br.ReadBytes((int)chunkLen0);
+ string json = System.Text.Encoding.UTF8.GetString(jsonBytes);
+
+ byte[] bin = new byte[0];
+ if (fs.Position + 8 <= fs.Length)
+ {
+ uint chunkLen1 = br.ReadUInt32();
+ uint chunkType1 = br.ReadUInt32();
+ bin = br.ReadBytes((int)chunkLen1);
+ }
+
+ return new GlbData(json, bin);
+ }
+ }
+
+ private static void WriteGlb(string path, string json, byte[] bin)
+ {
+ byte[] jsonBytes = System.Text.Encoding.UTF8.GetBytes(json);
+ jsonBytes = PadTo4(jsonBytes, 0x20);
+
+ byte[] binBytes = bin ?? new byte[0];
+ binBytes = PadTo4(binBytes, 0x00);
+
+ using (FileStream fs = File.Create(path))
+ using (BinaryWriter bw = new BinaryWriter(fs))
+ {
+ uint magic = 0x46546C67; // 'glTF'
+ uint version = 2;
+
+ uint length = 12 +
+ 8 + (uint)jsonBytes.Length +
+ (binBytes.Length > 0 ? (8 + (uint)binBytes.Length) : 0);
+
+ bw.Write(magic);
+ bw.Write(version);
+ bw.Write(length);
+
+ bw.Write((uint)jsonBytes.Length);
+ bw.Write(0x4E4F534A);
+ bw.Write(jsonBytes);
+
+ if (binBytes.Length > 0)
+ {
+ bw.Write((uint)binBytes.Length);
+ bw.Write(0x004E4942);
+ bw.Write(binBytes);
+ }
+ }
+ }
+
+ private static byte[] PadTo4(byte[] data, byte padByte)
+ {
+ int mod = data.Length % 4;
+ if (mod == 0) return data;
+
+ int pad = 4 - mod;
+ byte[] outArr = new byte[data.Length + pad];
+ Buffer.BlockCopy(data, 0, outArr, 0, data.Length);
+ for (int i = 0; i < pad; i++)
+ outArr[data.Length + i] = padByte;
+
+ return outArr;
+ }
+ }
+
+
+ //
+ // --------------------------------------------------------------------------------------
+ // DRACO COMPRESSION (unchanged)
+ // --------------------------------------------------------------------------------------
+ //
+
public static class Draco
{
public static void Compress(Preferences preferences)
@@ -19,74 +449,105 @@ public static void Compress(Preferences preferences)
if (preferences.format == FormatEnum.gltf)
{
- fileToCompress = string.Concat(preferences.path, ".gltf");
- fileToCompressTemp = string.Concat(preferences.path, "Temp.gltf");
+ fileToCompress = preferences.path + ".gltf";
+ fileToCompressTemp = preferences.path + "Temp.gltf";
- files.Add(string.Concat(preferences.path, ".bin"));
+ files.Add(preferences.path + ".bin");
files.Add(fileToCompress);
}
else
{
- fileToCompress = string.Concat(preferences.path, ".glb");
- fileToCompressTemp = string.Concat(preferences.path, "Temp.glb");
+ fileToCompress = preferences.path + ".glb";
+ fileToCompressTemp = preferences.path + "Temp.glb";
files.Add(fileToCompress);
}
#if REVIT2025 || REVIT2026
-
var loadContext = new NonCollectibleAssemblyLoadContext();
-
string programDataPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
string assemblyPath = Path.Combine(programDataPath, "Autodesk", "ApplicationPlugins", "leia.bundle", "Contents", "2025", "DracoWrapper.dll");
-
Assembly mixedModeAssembly = loadContext.LoadFromAssemblyPath(assemblyPath);
var gltfDecoderType = mixedModeAssembly.GetType("dracowrapper.GltfDecoder");
var gltfDecoderInstance = Activator.CreateInstance(gltfDecoderType);
- var decodeFromFileToSceneMethod = gltfDecoderType.GetMethod("DecodeFromFileToScene");
- var res = decodeFromFileToSceneMethod.Invoke(gltfDecoderInstance, new object[] { fileToCompress });
+ var decodeMethod = gltfDecoderType.GetMethod("DecodeFromFileToScene");
+ var res = decodeMethod.Invoke(gltfDecoderInstance, new object[] { fileToCompress });
var resType = res.GetType();
var valueMethod = resType.GetMethod("Value");
var scene = valueMethod.Invoke(res, null);
- var dracoCompressionOptionsType = mixedModeAssembly.GetType("dracowrapper.DracoCompressionOptions");
- var dracoCompressionOptionsInstance = Activator.CreateInstance(dracoCompressionOptionsType);
+ var optionsType = mixedModeAssembly.GetType("dracowrapper.DracoCompressionOptions");
+ var optionsInstance = Activator.CreateInstance(optionsType);
var sceneUtilsType = mixedModeAssembly.GetType("dracowrapper.SceneUtils");
- var setDracoCompressionOptionsMethod = sceneUtilsType.GetMethod("SetDracoCompressionOptions");
- setDracoCompressionOptionsMethod.Invoke(null, new object[] { dracoCompressionOptionsInstance, scene });
+ var setMethod = sceneUtilsType.GetMethod("SetDracoCompressionOptions");
+ setMethod.Invoke(null, new object[] { optionsInstance, scene });
- var gltfEncoderType = mixedModeAssembly.GetType("dracowrapper.GltfEncoder");
- var gltfEncoderInstance = Activator.CreateInstance(gltfEncoderType);
- var encodeSceneToFileMethod = gltfEncoderType.GetMethod("EncodeSceneToFile");
- encodeSceneToFileMethod.Invoke(gltfEncoderInstance, new object[] { scene, fileToCompressTemp });
+ var encoderType = mixedModeAssembly.GetType("dracowrapper.GltfEncoder");
+ var encoderInstance = Activator.CreateInstance(encoderType);
+ var encodeMethod = encoderType.GetMethod("EncodeSceneToFile");
+ encodeMethod.Invoke(encoderInstance, new object[] { scene, fileToCompressTemp });
#else
-
var decoder = new GltfDecoder();
var res = decoder.DecodeFromFileToScene(fileToCompress);
var scene = res.Value();
+
DracoCompressionOptions options = new DracoCompressionOptions();
SceneUtils.SetDracoCompressionOptions(options, scene);
+
var encoder = new GltfEncoder();
encoder.EncodeSceneToFile(scene, fileToCompressTemp);
+#endif
+
+ GltfExtrasPatcher.PatchExtras(fileToCompress, fileToCompressTemp);
- #endif
+ foreach (string x in files)
+ {
+ try
+ {
+ if (File.Exists(x)) File.Delete(x);
+ }
+ catch
+ {
+ }
+ }
- files.ForEach(x => File.Delete(x));
- File.Move(fileToCompressTemp, fileToCompress);
+ File_MoveOverwrite(fileToCompressTemp, fileToCompress);
if (preferences.format == FormatEnum.gltf)
{
- string binToReplace = fileToCompressTemp.Replace(".gltf", ".bin");
- string binFinalName = fileToCompressTemp.Replace("Temp.gltf", ".bin");
- File.Move(binToReplace, binFinalName);
+ string binTemp = fileToCompressTemp.Replace(".gltf", ".bin");
+ string binFinal = preferences.path + ".bin";
+
+ if (File.Exists(binTemp))
+ {
+ File_MoveOverwrite(binTemp, binFinal);
+ }
- string text = File.ReadAllText(fileToCompress);
- text = text.Replace(Path.GetFileName(binToReplace), Path.GetFileName(binFinalName));
- File.WriteAllText(fileToCompress, text);
+ if (File.Exists(fileToCompress))
+ {
+ string text = File.ReadAllText(fileToCompress);
+ string binTempName = Path.GetFileName(binTemp);
+ string binFinalName = Path.GetFileName(binFinal);
+ if (!string.IsNullOrEmpty(binTempName) && !string.IsNullOrEmpty(binFinalName))
+ {
+ text = text.Replace(binTempName, binFinalName);
+ File.WriteAllText(fileToCompress, text);
+ }
+ }
+ }
+ }
+
+ private static void File_MoveOverwrite(string src, string dst)
+ {
+ if (File.Exists(dst))
+ {
+ try { File.Delete(dst); }
+ catch { }
}
+ File.Move(src, dst);
}
}
}
diff --git a/Common_glTF_Exporter/Export/FileExport.cs b/Common_glTF_Exporter/Export/FileExport.cs
index 522d7d0..a239063 100644
--- a/Common_glTF_Exporter/Export/FileExport.cs
+++ b/Common_glTF_Exporter/Export/FileExport.cs
@@ -1,13 +1,16 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text;
-using Autodesk.Revit.DB;
+using Autodesk.Revit.DB;
using Common_glTF_Exporter.Core;
+using Common_glTF_Exporter.Model;
using Common_glTF_Exporter.Windows.MainWindow;
-using Newtonsoft.Json;
+using glTF.Manipulator.GenericSchema;
+using glTF.Manipulator.Schema;
+using glTF.Manipulator.Utils;
using Revit_glTF_Exporter;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using Buffer = glTF.Manipulator.Schema.Buffer;
+using Material = glTF.Manipulator.Schema.Material;
namespace Common_glTF_Exporter.Export
{
@@ -18,21 +21,22 @@ public static class FileExport
public static void Run(
Preferences preferences,
- List bufferViews,
- List buffers,
- List binaryFileData, List scenes,
- IndexedDictionary nodes,
- IndexedDictionary meshes,
- IndexedDictionary materials,
- List accessors,
- List textures,
- List images)
+ List bufferViews,
+ List buffers,
+ GLTFBinaryData binaryFileData,
+ List scenes,
+ IndexedDictionary nodes,
+ IndexedDictionary meshes,
+ IndexedDictionary materials,
+ List accessors,
+ List textures,
+ List images)
{
if (preferences.format == FormatEnum.gltf)
{
BufferConfig.Run(bufferViews, buffers, preferences);
string fileDirectory = string.Concat(preferences.path, BIN);
- BinFile.Create(fileDirectory, binaryFileData, preferences);
+ BinFile.Create(fileDirectory, binaryFileData);
string gltfJson = GltfJson.Get(scenes, nodes.List, meshes.List, materials.List, buffers,
bufferViews, accessors, textures, images, preferences);
diff --git a/Common_glTF_Exporter/Export/GlbBinInfo.cs b/Common_glTF_Exporter/Export/GlbBinInfo.cs
index 33a469f..2dffdcc 100644
--- a/Common_glTF_Exporter/Export/GlbBinInfo.cs
+++ b/Common_glTF_Exporter/Export/GlbBinInfo.cs
@@ -1,89 +1,41 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Autodesk.Revit.DB.Visual;
-using Common_glTF_Exporter.Core;
using Common_glTF_Exporter.Model;
-using Common_glTF_Exporter.Windows.MainWindow;
+using glTF.Manipulator.GenericSchema;
namespace Common_glTF_Exporter.Export
{
public static class GlbBinInfo
{
- public static byte[] Get(List binaryFileData, Preferences preferences)
+ public static byte[] Get(GLTFBinaryData globalBuffer)
{
- List binData = new List();
-
- foreach (var bin in binaryFileData)
- {
- foreach (var coord in bin.vertexBuffer)
- {
- List vertex = BitConverter.GetBytes((float)coord).ToList();
- binData.AddRange(vertex);
- }
-
- if (preferences.normals)
- {
- foreach (var normal in bin.normalBuffer)
- {
- List normalBuffer = BitConverter.GetBytes((float)normal).ToList();
- binData.AddRange(normalBuffer);
- }
- }
+ GlbBin glbBin = new GlbBin();
- if (preferences.materials == MaterialsEnum.textures)
- {
- if (bin.byteData != null)
- {
- binData.AddRange(bin.byteData);
- }
+ // Usar MemoryStream → ToArray()
+ glbBin.ChunkData = globalBuffer.ToArray();
- if (bin.uvBuffer != null && bin.uvBuffer.Count > 0)
- {
- foreach (var uv in bin.uvBuffer)
- {
- List uvBytes = BitConverter.GetBytes((float)uv).ToList();
- binData.AddRange(uvBytes);
- }
- }
- }
+ // Length del chunk BIN
+ glbBin.Length = BitConverter.GetBytes((uint)glbBin.ChunkData.Length);
- if (preferences.batchId)
- {
- foreach (var batchId in bin.batchIdBuffer)
- {
- List batchIdBuffer = BitConverter.GetBytes((float)batchId).ToList();
- binData.AddRange(batchIdBuffer);
- }
- }
+ // 📌 Construcción del chunk final:
+ // [byteLength][CHUNK_TYPE][binary data]
+ byte[] result = new byte[
+ glbBin.Length.Length
+ + glbBin.ChunkType().Length
+ + glbBin.ChunkData.Length];
- foreach (var index in bin.indexBuffer)
- {
- List indexIdBuffer = BitConverter.GetBytes((int)index).ToList();
- binData.AddRange(indexIdBuffer);
- }
- }
+ int offset = 0;
- if (binData.Count % 4 != 0)
- {
- int missingNumbers = 4 - (binData.Count % 4);
- for (int i = 0; i < missingNumbers; i++)
- {
- byte emptyByte = (byte)00;
- List zeros = new List { emptyByte };
- binData.AddRange(zeros);
- }
- }
+ // Copiar chunk length
+ Buffer.BlockCopy(glbBin.Length, 0, result, offset, glbBin.Length.Length);
+ offset += glbBin.Length.Length;
- GlbBin glbBin = new GlbBin();
- glbBin.ChunkData = binData.ToArray();
- glbBin.Length = BitConverter.GetBytes(Convert.ToUInt32(glbBin.ChunkData.Length));
+ // Copiar chunk type
+ byte[] type = glbBin.ChunkType();
+ Buffer.BlockCopy(type, 0, result, offset, type.Length);
+ offset += type.Length;
- byte[] result = new byte[] { };
- result = result.Concat(glbBin.Length).ToArray();
- result = result.Concat(glbBin.ChunkType()).ToArray();
- result = result.Concat(glbBin.ChunkData).ToArray();
+ // Copiar datos binarios
+ Buffer.BlockCopy(glbBin.ChunkData, 0, result, offset, glbBin.ChunkData.Length);
return result;
}
diff --git a/Common_glTF_Exporter/Export/GlbFile.cs b/Common_glTF_Exporter/Export/GlbFile.cs
index b86d25e..7ad56b9 100644
--- a/Common_glTF_Exporter/Export/GlbFile.cs
+++ b/Common_glTF_Exporter/Export/GlbFile.cs
@@ -6,16 +6,17 @@
using System.Windows.Forms;
using Common_glTF_Exporter.Core;
using Common_glTF_Exporter.Windows.MainWindow;
+using glTF.Manipulator.GenericSchema;
namespace Common_glTF_Exporter.Export
{
internal class GlbFile
{
- public static void Create(Preferences preferences, List binaryFileData, string json)
+ public static void Create(Preferences preferences, GLTFBinaryData binaryFileData, string json)
{
byte[] jsonChunk = GlbJsonInfo.Get(json);
int lenggg = jsonChunk.Length;
- byte[] binChunk = GlbBinInfo.Get(binaryFileData, preferences);
+ byte[] binChunk = GlbBinInfo.Get(binaryFileData);
byte[] headerChunk = GlbHeaderInfo.Get(jsonChunk, binChunk);
string fileDirectory = string.Concat(preferences.path, ".glb");
diff --git a/Common_glTF_Exporter/Export/GltfJson.cs b/Common_glTF_Exporter/Export/GltfJson.cs
index 4fb8230..a420781 100644
--- a/Common_glTF_Exporter/Export/GltfJson.cs
+++ b/Common_glTF_Exporter/Export/GltfJson.cs
@@ -1,33 +1,39 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Autodesk.Revit.DB;
-using Common_glTF_Exporter.Core;
+using Common_glTF_Exporter.Utils;
using Common_glTF_Exporter.Windows.MainWindow;
+using glTF.Manipulator.GenericSchema;
+using glTF.Manipulator.Schema;
using Newtonsoft.Json;
-using Revit_glTF_Exporter;
+using System.Collections.Generic;
+using System.Linq;
+using Buffer = glTF.Manipulator.Schema.Buffer;
namespace Common_glTF_Exporter.Export
{
public static class GltfJson
{
public static string Get(
- List scenes,
- List nodes,
- List meshes,
- List materials,
- List buffers,
- List bufferViews,
- List accessors,
- List textures,
- List images,
+ List scenes,
+ List nodes,
+ List meshes,
+ List materials,
+ List buffers,
+ List bufferViews,
+ List accessors,
+ List textures,
+ List images,
Preferences preferences)
{
+ glTF.Manipulator.Schema.Version version = new glTF.Manipulator.Schema.Version
+ {
+ version = "2.0",
+ generator = string.Concat("e-verse custom generator ", SettingsConfig.currentVersion),
+ copyright = "free tool created by e-verse"
+ };
+
GLTF model = new GLTF
{
- asset = new GLTFVersion(),
+ asset = version,
scenes = scenes,
nodes = nodes,
meshes = meshes,
@@ -38,9 +44,9 @@ public static string Get(
model.extensionsUsed = new List { "KHR_texture_transform" };
}
- if (materials.Any())
+ if (materials.Any() && preferences.materials != MaterialsEnum.nonematerials)
{
- model.materials = materials;
+ model.materials = transformMaterials(materials);
}
if (preferences.materials == MaterialsEnum.textures)
@@ -52,7 +58,7 @@ public static string Get(
if (images.Any())
{
- model.images = images;
+ model.images = cleanImages(images);
}
}
@@ -60,12 +66,76 @@ public static string Get(
model.bufferViews = bufferViews;
model.accessors = accessors;
- // Write the *.gltf file
- string serializedModel = JsonConvert.SerializeObject(
- model,
- new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
+ // ---------------------------
+ // NEWTONSOFT JSON SETTINGS
+ // ---------------------------
+ var settings = new JsonSerializerSettings
+ {
+ NullValueHandling = NullValueHandling.Ignore,
+ Formatting = Newtonsoft.Json.Formatting.None
+ };
+ string serializedModel = JsonConvert.SerializeObject(model, settings);
return serializedModel;
}
+
+ public static List cleanImages(List images)
+ {
+ List resultImages = new List();
+ foreach (glTFImage img in images)
+ {
+ glTFImage newImg = new glTFImage
+ {
+ bufferView = img.bufferView,
+ mimeType = img.mimeType
+ };
+
+ resultImages.Add(newImg);
+ }
+
+ return resultImages;
+ }
+
+ public static List transformMaterials(List baseMaterials)
+ {
+ List materials = new List();
+
+ foreach (BaseMaterial baseMat in baseMaterials)
+ {
+ glTF.Manipulator.Schema.Material mat = new glTF.Manipulator.Schema.Material();
+ mat.alphaMode = baseMat.alphaMode;
+ mat.alphaCutoff = baseMat.alphaCutoff;
+ mat.name = baseMat.name;
+ mat.doubleSided = baseMat.doubleSided;
+
+ PBR pbrMetallicRoughness = new PBR();
+ pbrMetallicRoughness.metallicFactor = baseMat.metallicFactor;
+ pbrMetallicRoughness.baseColorFactor = baseMat.baseColorFactor;
+ pbrMetallicRoughness.roughnessFactor = baseMat.roughnessFactor;
+
+ if (baseMat.hasTexture)
+ {
+ TextureInfo baseColorTexture = new TextureInfo();
+ baseColorTexture.index = baseMat.textureIndex;
+
+ KHR_texture_transform kHR_Texture_Transform = new KHR_texture_transform();
+ kHR_Texture_Transform.rotation = baseMat.rotation;
+ kHR_Texture_Transform.scale = baseMat.scale;
+ kHR_Texture_Transform.offset = baseMat.offset;
+
+ TextureExtensions extensions = new TextureExtensions();
+ extensions.KHR_texture_transform = kHR_Texture_Transform;
+
+ baseColorTexture.extensions = extensions;
+ pbrMetallicRoughness.baseColorTexture = baseColorTexture;
+ }
+
+ mat.pbrMetallicRoughness = pbrMetallicRoughness;
+
+ materials.Add(mat);
+ }
+
+ return materials;
+ }
}
}
diff --git a/Common_glTF_Exporter/Export/RevitGrids.cs b/Common_glTF_Exporter/Export/RevitGrids.cs
index 57bd704..9b3a2c1 100644
--- a/Common_glTF_Exporter/Export/RevitGrids.cs
+++ b/Common_glTF_Exporter/Export/RevitGrids.cs
@@ -1,11 +1,13 @@
-namespace Common_glTF_Exporter.Export
-{
- using System.Collections.Generic;
- using Autodesk.Revit.DB;
- using Common_glTF_Exporter.Core;
- using Common_glTF_Exporter.Windows.MainWindow;
- using Revit_glTF_Exporter;
+using Autodesk.Revit.DB;
+using Common_glTF_Exporter.Windows.MainWindow;
+using glTF.Manipulator.Schema;
+using glTF.Manipulator.Utils;
+using Revit_glTF_Exporter;
+using System.Collections.Generic;
+using System.Globalization;
+namespace Common_glTF_Exporter.Export
+{
///
/// Revit grids.
///
@@ -18,7 +20,7 @@ public static class RevitGrids
/// Nodes.
/// root node.
/// preferences.
- public static void Export(Document doc, ref IndexedDictionary nodes, ref GLTFNode rootNode, Preferences preferences)
+ public static void Export(Document doc, ref IndexedDictionary nodes, ref Node rootNode, Preferences preferences)
{
using (FilteredElementCollector col = new FilteredElementCollector(doc).OfClass(typeof(Grid)))
{
@@ -38,25 +40,33 @@ public static void Export(Document doc, ref IndexedDictionary nodes, r
var direction = l.Direction;
var length = l.Length;
- var xtras = new GLTFExtras();
- var grid = new RevitGridParametersObject();
+ Extras xtras = new Extras();
- grid.origin = new List() { origin.X, origin.Y, origin.Z };
+ Dictionary parameters = preferences.properties
+ ? Util.GetElementParameters(g, true) ?? new Dictionary()
+ : new Dictionary();
- grid.direction = new List() { direction.X, direction.Y, direction.Z, };
- grid.length = length;
+ parameters["UniqueId"] = g.UniqueId;
- xtras.gridParameters = grid;
- xtras.uniqueId = g.UniqueId;
+ parameters["GridOrigin"] = string.Format(
+ CultureInfo.InvariantCulture,
+ "{0},{1},{2}",
+ origin.X, origin.Y, origin.Z);
- if (preferences.properties)
- {
- xtras.parameters = Util.GetElementParameters(g, true);
- }
+ parameters["GridDirection"] = string.Format(
+ CultureInfo.InvariantCulture,
+ "{0},{1},{2}",
+ direction.X, direction.Y, direction.Z);
- var gridNode = new GLTFNode();
- gridNode.name = g.Name;
- gridNode.extras = xtras;
+ parameters["GridLength"] = length.ToString(CultureInfo.InvariantCulture);
+
+ xtras.parameters = parameters;
+
+ Node gridNode = new Node
+ {
+ name = g.Name,
+ extras = xtras
+ };
nodes.AddOrUpdateCurrent(g.UniqueId, gridNode);
rootNode.children.Add(nodes.CurrentIndex);
diff --git a/Common_glTF_Exporter/ExternalApplication.cs b/Common_glTF_Exporter/ExternalApplication.cs
index 0d1a130..61771a0 100644
--- a/Common_glTF_Exporter/ExternalApplication.cs
+++ b/Common_glTF_Exporter/ExternalApplication.cs
@@ -5,6 +5,7 @@
using Autodesk.Windows;
using Common_glTF_Exporter;
using Common_glTF_Exporter.Service;
+ using Common_glTF_Exporter.Version;
using System;
using System.IO;
using System.Linq;
@@ -25,6 +26,7 @@ public class ExternalApplication : IExternalApplication
private static string pushButtonText = "Leia";
private static string addInPath = typeof(ExternalApplication).Assembly.Location;
private static string buttonIconsFolder = Path.GetDirectoryName(addInPath) + "\\Images\\";
+ public static string InstallerRoute;
internal Document Document { get; set; }
public static UIApplication UiApp { get; private set; }
@@ -57,6 +59,10 @@ public static void CreateRibbonTab(UIControlledApplication application, string r
/// Result.
public Result OnShutdown(UIControlledApplication application)
{
+ if (!string.IsNullOrEmpty(InstallerRoute))
+ {
+ RunLocalFile.Action(InstallerRoute);
+ }
return Result.Succeeded;
}
diff --git a/Common_glTF_Exporter/Materials/BitmapsUtils.cs b/Common_glTF_Exporter/Materials/BitmapsUtils.cs
index b470f64..1d6f8ec 100644
--- a/Common_glTF_Exporter/Materials/BitmapsUtils.cs
+++ b/Common_glTF_Exporter/Materials/BitmapsUtils.cs
@@ -30,6 +30,28 @@ public static (string, ImageFormat) GetMimeType(string path)
}
}
+ ///
+ /// Removes non-default gamma or ICC profile metadata from a PNG/JPG file
+ /// by re-encoding it to a clean sRGB version in memory.
+ ///
+ /// Path to the source image
+ /// Byte array of the cleaned image (PNG)
+ public static byte[] CleanGamma(string path, ImageFormat imageFormat)
+ {
+ using (var original = new Bitmap(path))
+ using (var ms = new MemoryStream())
+ {
+ // Convert to standard sRGB (System.Drawing assumes sRGB by default)
+ using (var converted = new Bitmap(original.Width, original.Height, PixelFormat.Format24bppRgb))
+ using (var g = Graphics.FromImage(converted))
+ {
+ g.DrawImage(original, 0, 0, original.Width, original.Height);
+ converted.Save(ms, imageFormat);
+ }
+ return ms.ToArray();
+ }
+ }
+
public static byte[] BlendImageWithColor(
byte[] imageBytes,
double fade,
diff --git a/Common_glTF_Exporter/Materials/MaterialProperties.cs b/Common_glTF_Exporter/Materials/MaterialProperties.cs
index b5de6fd..f74d389 100644
--- a/Common_glTF_Exporter/Materials/MaterialProperties.cs
+++ b/Common_glTF_Exporter/Materials/MaterialProperties.cs
@@ -1,9 +1,13 @@
using System;
using System.Collections.Generic;
using System.IO.Ports;
+using System.Linq;
using System.Xml.Linq;
using Autodesk.Revit.DB;
using Common_glTF_Exporter.Core;
+using Common_glTF_Exporter.Model;
+using glTF.Manipulator.GenericSchema;
+using glTF.Manipulator.Schema;
namespace Common_glTF_Exporter.Materials
{
@@ -11,52 +15,43 @@ public static class MaterialProperties
{
private const string BLEND = "BLEND";
private const string OPAQUE = "OPAQUE";
- public static void SetProperties(MaterialNode node, float opacity, ref GLTFPBR pbr, ref GLTFMaterial gl_mat)
+ public static void SetProperties(MaterialNode node, float opacity, ref BaseMaterial material)
{
- pbr.metallicFactor = 0f;
- pbr.roughnessFactor = opacity != 1 ? 0.5f : 1f;
- gl_mat.pbrMetallicRoughness = pbr;
-
- gl_mat.alphaMode = opacity != 1 ? BLEND : OPAQUE;
- gl_mat.alphaCutoff = null;
+ material.metallicFactor = 0f;
+ material.roughnessFactor = opacity != 1 ? 0.5f : 1f;
+ material.alphaMode = opacity != 1 ? BLEND : OPAQUE;
+ material.alphaCutoff = null;
}
- public static void SetMaterialColour(MaterialNode node,
- float opacity, ref GLTFPBR pbr, ref GLTFMaterial gl_mat)
+ public static List SetMaterialColour(MaterialNode node,
+ float opacity, Autodesk.Revit.DB.Color baseColor, Autodesk.Revit.DB.Color tintColor)
{
- if (gl_mat.EmbeddedTexturePath == null)
- {
+
(float, float, float) baseColours;
- if (gl_mat.BaseColor == null)
+ if (baseColor == null)
{
baseColours = RgbToUnit(node.Color);
}
else
{
- baseColours = RgbToUnit(gl_mat.BaseColor);
+ baseColours = RgbToUnit(baseColor);
}
- if (gl_mat.TintColour == null)
+ if (tintColor == null)
{
- pbr.baseColorFactor = GetLinearColour(baseColours, opacity);
+ return GetLinearColour(baseColours, opacity);
}
else
{
- (float, float, float) baseTintColour = RgbToUnit(gl_mat.TintColour);
+ (float, float, float) baseTintColour = RgbToUnit(tintColor);
(float, float, float) blendColour = BlendColour(baseColours, baseTintColour);
- pbr.baseColorFactor = GetLinearColour(blendColour, opacity);
+ return GetLinearColour(blendColour, opacity);
}
- }
- else
- {
- gl_mat.pbrMetallicRoughness.baseColorFactor = GetDefaultColour(opacity);
- }
-
- gl_mat.pbrMetallicRoughness = pbr;
}
+
public static List GetDefaultColour(float opacity)
{
return new List(4) { 1, 1, 1, opacity };
diff --git a/Common_glTF_Exporter/Materials/MaterialTexture.cs b/Common_glTF_Exporter/Materials/MaterialTexture.cs
new file mode 100644
index 0000000..cc9ec91
--- /dev/null
+++ b/Common_glTF_Exporter/Materials/MaterialTexture.cs
@@ -0,0 +1,12 @@
+namespace Common_glTF_Exporter.Core
+{
+ public class MaterialTexture
+ {
+ public string EmbeddedTexturePath { get; set; } = null;
+ public double Fadevalue { get; set; } = 1;
+
+ public Autodesk.Revit.DB.Color TintColour { get; set; }
+
+ public Autodesk.Revit.DB.Color BaseColor { get; set; }
+ }
+}
diff --git a/Common_glTF_Exporter/Materials/MaterialTextures.cs b/Common_glTF_Exporter/Materials/MaterialTextures.cs
index 74d0455..c162a6b 100644
--- a/Common_glTF_Exporter/Materials/MaterialTextures.cs
+++ b/Common_glTF_Exporter/Materials/MaterialTextures.cs
@@ -1,66 +1,71 @@
-using System.Collections.Generic;
-using System.IO;
-using Autodesk.Revit.DB;
+using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Visual;
using Common_glTF_Exporter.Core;
-using Common_glTF_Exporter.Windows.MainWindow;
-using Revit_glTF_Exporter;
-using Common_glTF_Exporter.Materials;
using Common_glTF_Exporter.Model;
-using System.IO.Ports;
-using System.Windows.Controls;
-using System.Windows.Media.Media3D;
+using glTF.Manipulator.GenericSchema;
+using glTF.Manipulator.Schema;
+using Revit_glTF_Exporter;
+using System.Collections.Generic;
+using System.Drawing.Imaging;
+using System.IO;
+using System.Linq;
+using System.Windows.Interop;
using Material = Autodesk.Revit.DB.Material;
-using System;
-using Common_glTF_Exporter.Utils;
-using System.Diagnostics;
namespace Common_glTF_Exporter.Materials
{
public static class MaterialTextures
{
- public static GLTFMaterial SetMaterialTextures(Material material, GLTFMaterial gl_mat,
- Document doc, float opacity)
+ public static (Autodesk.Revit.DB.Color, Autodesk.Revit.DB.Color) SetMaterialTextures(Material revitMaterial, BaseMaterial material,
+ Document doc, float opacity, List textures, List images)
{
- ElementId appearanceId = material.AppearanceAssetId;
+ ElementId appearanceId = revitMaterial.AppearanceAssetId;
if (appearanceId == ElementId.InvalidElementId)
{
- return gl_mat;
+ return (null,null);
}
var appearanceElem = doc.GetElement(appearanceId) as AppearanceAssetElement;
if (appearanceElem == null)
{
- return gl_mat;
+ return (null, null);
}
Asset theAsset = appearanceElem.GetRenderingAsset();
AssetPropertyString baseSchema = theAsset.FindByName("BaseSchema") as AssetPropertyString;
if (baseSchema == null)
{
- return gl_mat;
+ return (null, null);
}
string schemaName = baseSchema.Value;
Asset connectedAsset = AssetPropertiesUtils.GetDiffuseBitmap(theAsset, schemaName);
string texturePath = AssetPropertiesUtils.GetTexturePath(connectedAsset);
- gl_mat.TintColour = AssetPropertiesUtils.GetTint(theAsset);
- gl_mat.BaseColor = AssetPropertiesUtils.GetAppearanceColor(theAsset, schemaName);
+ Autodesk.Revit.DB.Color tintColour = AssetPropertiesUtils.GetTint(theAsset);
+ Autodesk.Revit.DB.Color baseColor = AssetPropertiesUtils.GetAppearanceColor(theAsset, schemaName);
+ double Fadevalue = AssetPropertiesUtils.GetFade(theAsset);
- if (!string.IsNullOrEmpty(texturePath) && File.Exists(texturePath))
+ if (!string.IsNullOrEmpty(texturePath))
{
- SetTextureProperties(gl_mat, texturePath, connectedAsset, theAsset, opacity);
+ int indexImage = createOrGetBaseImage(tintColour, baseColor, Fadevalue, texturePath, images);
+
+ Texture baseTexture = createTexture(material, texturePath, connectedAsset, theAsset, opacity, indexImage);
+ textures.Add(baseTexture);
+
+ material.hasTexture = true;
+ material.textureIndex = textures.Count - 1;
}
- return gl_mat;
+ return (baseColor, tintColour);
}
- private static void SetTextureProperties(GLTFMaterial gl_mat, string texturePath, Asset connectedAsset,
- Asset theAsset, float opacity)
+ private static Texture createTexture(BaseMaterial material, string texturePath, Asset connectedAsset,
+ Asset theAsset, float opacity, int imageIndex)
{
- gl_mat.EmbeddedTexturePath = texturePath;
+
+ Texture texture = new Texture();
float scaleX = AssetPropertiesUtils.GetScale(connectedAsset, UnifiedBitmap.TextureRealWorldScaleX);
float scaleY = AssetPropertiesUtils.GetScale(connectedAsset, UnifiedBitmap.TextureRealWorldScaleY);
@@ -68,8 +73,6 @@ private static void SetTextureProperties(GLTFMaterial gl_mat, string texturePath
float offsetY = AssetPropertiesUtils.GetOffset(connectedAsset, UnifiedBitmap.TextureRealWorldOffsetY);
float rotation = AssetPropertiesUtils.GetRotationRadians(connectedAsset);
- gl_mat.Fadevalue = AssetPropertiesUtils.GetFade(theAsset);
-
float[] gltfScale = new float[] { 1f / scaleX, 1f / scaleY };
float[] gltfOffset = new float[]
{
@@ -77,19 +80,40 @@ private static void SetTextureProperties(GLTFMaterial gl_mat, string texturePath
offsetY / scaleY - gltfScale[1]
};
- gl_mat.pbrMetallicRoughness.baseColorTexture = new GLTFTextureInfo
+ material.offset = gltfOffset;
+ material.rotation = rotation;
+ material.scale = gltfScale;
+ texture.source = imageIndex;
+
+ return texture;
+ }
+
+ private static int createOrGetBaseImage(Autodesk.Revit.DB.Color TintColour, Autodesk.Revit.DB.Color BaseColor, double Fadevalue, string texturePath, List images)
+ {
+
+ bool checkIfImageExists = images.Any(x => x.uuid == texturePath);
+
+ if (checkIfImageExists)
{
- index = -1,
- extensions = new GLTFTextureExtensions
- {
- TextureTransform = new GLTFTextureTransform
- {
- offset = gltfOffset,
- scale = gltfScale,
- rotation = rotation
- }
- }
- };
+ int index = images.FindIndex(x => x.uuid == texturePath);
+
+ return index;
+ }
+ else
+ {
+ glTFImage Image = new glTFImage();
+ Image.uuid = texturePath;
+ (string, ImageFormat) mimeType = BitmapsUtils.GetMimeType(texturePath);
+ Image.mimeType = mimeType.Item1;
+ byte[] imageBytes = BitmapsUtils.CleanGamma(texturePath, mimeType.Item2);
+ byte[] blendedBytes = BitmapsUtils.BlendImageWithColor(imageBytes, Fadevalue,
+ BaseColor, mimeType.Item2, TintColour);
+ Image.imageData = blendedBytes;
+ images.Add(Image);
+ int index = images.Count - 1;
+
+ return index;
+ }
}
}
}
diff --git a/Common_glTF_Exporter/Materials/RevitMaterials.cs b/Common_glTF_Exporter/Materials/RevitMaterials.cs
index 23e20a5..f1e9208 100644
--- a/Common_glTF_Exporter/Materials/RevitMaterials.cs
+++ b/Common_glTF_Exporter/Materials/RevitMaterials.cs
@@ -11,6 +11,10 @@
using System.Windows.Controls;
using System.Windows.Media.Media3D;
using Material = Autodesk.Revit.DB.Material;
+using Common_glTF_Exporter.Utils;
+using glTF.Manipulator.Schema;
+using glTF.Manipulator.GenericSchema;
+using glTF.Manipulator.Utils;
namespace Common_glTF_Exporter.Export
@@ -19,37 +23,69 @@ public static class RevitMaterials
{
const int ONEINTVALUE = 1;
- ///
- /// Export Revit materials.
- ///
- public static GLTFMaterial Export(MaterialNode node,
- Preferences preferences, Document doc)
+ public static BaseMaterial ProcessMaterial(MaterialNode node,
+ Preferences preferences, Document doc, IndexedDictionary materials,
+ List textures, List images)
{
- GLTFMaterial gl_mat = new GLTFMaterial();
- float opacity = ONEINTVALUE - (float)node.Transparency;
+ BaseMaterial material = new BaseMaterial();
+ string materialId = node.MaterialId.ToString();
+ material.uuid = materialId;
- Material material = doc.GetElement(node.MaterialId) as Material;
+ if (materials.Contains(materialId))
+ {
+ material = materials.GetElement(materialId);
+ }
+ else
+ {
+ Autodesk.Revit.DB.Material revitMaterial = doc.GetElement(node.MaterialId) as Autodesk.Revit.DB.Material;
- if (material == null)
+ if (revitMaterial == null)
+ {
+ material = GLTFExportUtils.GetGLTFMaterial(materials);
+ }
+ else
{
- return gl_mat;
+ material = RevitMaterials.Export(node, preferences, doc, revitMaterial, textures, images, material);
}
+ }
+ materials.AddOrUpdateCurrentMaterial(material.uuid, material, false);
- gl_mat.name = material.Name;
- gl_mat.UniqueId = node.MaterialId.ToString();
+ return material;
+ }
- GLTFPBR pbr = new GLTFPBR();
- MaterialProperties.SetProperties(node, opacity, ref pbr, ref gl_mat);
- if (material != null && preferences.materials == MaterialsEnum.textures)
+ ///
+ /// Export Revit materials.
+ ///
+ public static BaseMaterial Export(MaterialNode node,
+ Preferences preferences, Document doc,
+ Material revitMaterial, List textures,
+ List images, BaseMaterial material)
+ {
+
+ float opacity = ONEINTVALUE - (float)node.Transparency;
+
+ material.name = revitMaterial.Name;
+ MaterialProperties.SetProperties(node, opacity, ref material);
+
+ (Autodesk.Revit.DB.Color, Autodesk.Revit.DB.Color) baseNTintColour = (null, null);
+
+ if (revitMaterial != null && preferences.materials == MaterialsEnum.textures)
{
- MaterialTextures.SetMaterialTextures(material, gl_mat, doc, opacity);
+ baseNTintColour = MaterialTextures.SetMaterialTextures(revitMaterial, material, doc, opacity, textures, images);
+ material.baseColorFactor = MaterialProperties.GetDefaultColour(opacity);
}
- MaterialProperties.SetMaterialColour(node, opacity, ref pbr, ref gl_mat);
-
+ if (material.hasTexture)
+ {
+ material.baseColorFactor = MaterialProperties.GetDefaultColour(opacity);
+ }
+ else
+ {
+ material.baseColorFactor = MaterialProperties.SetMaterialColour(node, opacity, baseNTintColour.Item1, baseNTintColour.Item2);
+ }
- return gl_mat;
+ return material;
}
}
}
diff --git a/Common_glTF_Exporter/Model/GeometryDataObject.cs b/Common_glTF_Exporter/Model/GeometryDataObject.cs
deleted file mode 100644
index 2d0158a..0000000
--- a/Common_glTF_Exporter/Model/GeometryDataObject.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-namespace Common_glTF_Exporter.Model
-{
- using Autodesk.Revit.DB;
- using System.Collections.Generic;
-
- ///
- /// Intermediate data format for converting between Revit Polymesh and glTF buffers.
- ///
- public class GeometryDataObject
- {
- public List Vertices { get; set; } = new List();
-
- public List Normals { get; set; } = new List();
-
- public List Uvs { get; set; } = new List();
-
- public List Faces { get; set; } = new List();
-
- }
-}
diff --git a/Common_glTF_Exporter/Utils/GLTFBinaryDataUtils.cs b/Common_glTF_Exporter/Utils/GLTFBinaryDataUtils.cs
index 0039ad4..f6b283a 100644
--- a/Common_glTF_Exporter/Utils/GLTFBinaryDataUtils.cs
+++ b/Common_glTF_Exporter/Utils/GLTFBinaryDataUtils.cs
@@ -1,275 +1,345 @@
-using System.Drawing.Imaging;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using Common_glTF_Exporter.Core;
+using Common_glTF_Exporter.Core;
using Common_glTF_Exporter.Model;
+using glTF.Manipulator.GenericSchema;
+using glTF.Manipulator.Schema;
using Revit_glTF_Exporter;
-using Common_glTF_Exporter.Materials;
+using System.Collections.Generic;
+using System.Linq;
namespace Common_glTF_Exporter.Utils
{
public class GLTFBinaryDataUtils
{
- const string SCALAR_STR = "SCALAR";
- const string FACE_STR = "FACE";
- const string BATCH_ID_STR = "BATCH_ID";
-
- public static int ExportFaces(int bufferIdx, int byteOffset, GeometryDataObject geomData, GLTFBinaryData bufferData, List bufferViews, List accessors)
+ public static int ExportFaces(
+ GeometryDataObject geomData,
+ GLTFBinaryData bufferData,
+ List bufferViews,
+ List accessors)
{
- foreach (var index in geomData.Faces)
- {
- bufferData.indexBuffer.Add(index);
- }
-
- // Get max and min for index data
- int[] faceMinMax = Util.GetScalarMinMax(bufferData.indexBuffer);
-
- // Add a faces / indexes buffer view
- int elementsPerIndex = 1;
- int bytesPerIndexElement = 4;
- int bytesPerIndex = elementsPerIndex * bytesPerIndexElement;
- int numIndexes = geomData.Faces.Count;
- int sizeOfIndexView = numIndexes * bytesPerIndex;
- GLTFBufferView facesView = new GLTFBufferView(bufferIdx, byteOffset, sizeOfIndexView, Targets.ELEMENT_ARRAY_BUFFER, string.Empty);
- bufferViews.Add(facesView);
- int facesViewIdx = bufferViews.Count - 1;
-
- // add a face accessor
- var count = geomData.Faces.Count / elementsPerIndex;
- var max = new List(1) { faceMinMax[1] };
- var min = new List(1) { faceMinMax[0] };
- GLTFAccessor faceAccessor = new GLTFAccessor(facesViewIdx, 0, ComponentType.UNSIGNED_INT, count, SCALAR_STR, max, min, FACE_STR);
- accessors.Add(faceAccessor);
- bufferData.indexAccessorIndex = accessors.Count - 1;
- return byteOffset + facesView.byteLength;
+ const string SCALAR_STR = "SCALAR";
+ const string FACE_STR = "FACE";
+
+ int indexCount = geomData.Faces.Count;
+ if (indexCount == 0)
+ return -1;
+
+ int[] indices = geomData.Faces.ToArray();
+
+ List listIndicess = new List(indices);
+ int[] minMax = Util.GetScalarMinMax(listIndicess);
+
+ var max = new List { minMax[1] };
+ var min = new List { minMax[0] };
+
+ int byteOffset = bufferData.AppendIntArray(indices);
+ int byteLength = indices.Length * sizeof(int);
+
+ BufferView view = new BufferView(
+ buffer: 0,
+ byteOffset: byteOffset,
+ byteLength: byteLength,
+ Targets.ELEMENT_ARRAY_BUFFER,
+ name: ""
+ );
+
+ bufferViews.Add(view);
+ int viewIdx = bufferViews.Count - 1;
+
+ Accessor accessor = new Accessor(
+ bufferView: viewIdx,
+ byteOffset: 0,
+ componentType: ComponentType.UNSIGNED_INT, // 5125
+ count: indexCount,
+ type: SCALAR_STR,
+ max: max,
+ min: min,
+ name: FACE_STR
+ );
+
+ accessors.Add(accessor);
+ int accessorIdx = accessors.Count - 1;
+
+ return accessorIdx;
}
+
const string VEC3_STR = "VEC3";
const string POSITION_STR = "POSITION";
- public static int ExportVertices(int bufferIdx, int byteOffset, GeometryDataObject geomData, GLTFBinaryData bufferData, List bufferViews, List accessors, out int sizeOfVec3View, out int elementsPerVertex)
+ public static int ExportVertices(
+ GeometryDataObject geomData,
+ GLTFBinaryData bufferData,
+ List bufferViews,
+ List accessors,
+ MeshPrimitive primitive)
{
+ const string VEC3_STR = "VEC3";
+ const string POSITION_STR = "POSITION";
- for (int i = 0; i < geomData.Vertices.Count; i++)
- {
- bufferData.vertexBuffer.Add(Convert.ToSingle(geomData.Vertices[i]));
- }
+ int vertexCount = geomData.Vertices.Count / 3;
+ if (vertexCount == 0)
+ return -1;
- // Get max and min for vertex data
- float[] vertexMinMax = Util.GetVec3MinMax(bufferData.vertexBuffer);
-
- // Add a vec3 buffer view
- elementsPerVertex = 3;
- int bytesPerElement = 4;
- int bytesPerVertex = elementsPerVertex * bytesPerElement;
- int numVec3 = geomData.Vertices.Count / elementsPerVertex;
- sizeOfVec3View = numVec3 * bytesPerVertex;
-
- GLTFBufferView vec3View = new GLTFBufferView(bufferIdx, byteOffset, sizeOfVec3View, Targets.ARRAY_BUFFER, string.Empty);
- bufferViews.Add(vec3View);
- int vec3ViewIdx = bufferViews.Count - 1;
-
- // add a position accessor
- int count = geomData.Vertices.Count / elementsPerVertex;
- var max = new List(3) { vertexMinMax[1], vertexMinMax[3], vertexMinMax[5] };
- var min = new List(3) { vertexMinMax[0], vertexMinMax[2], vertexMinMax[4] };
-
- GLTFAccessor positionAccessor = new GLTFAccessor(vec3ViewIdx, 0, ComponentType.FLOAT, count, VEC3_STR, max, min, POSITION_STR);
- accessors.Add(positionAccessor);
- bufferData.vertexAccessorIndex = accessors.Count - 1;
- return byteOffset + vec3View.byteLength;
+ // Convert to float array
+ float[] vertexFloats = new float[geomData.Vertices.Count];
+ for (int i = 0; i < geomData.Vertices.Count; i++)
+ vertexFloats[i] = (float)geomData.Vertices[i];
+
+ // Compute min/max
+ float[] minMax = Util.GetVec3MinMax(vertexFloats);
+ var max = new List { minMax[1], minMax[3], minMax[5] };
+ var min = new List { minMax[0], minMax[2], minMax[4] };
+
+ // Write to buffer (correct padding applied)
+ int byteOffset = bufferData.AppendFloatArray(vertexFloats);
+ int byteLength = vertexFloats.Length * sizeof(float);
+
+ // Create bufferView
+ var view = new BufferView(
+ buffer: 0,
+ byteOffset: byteOffset,
+ byteLength: byteLength,
+ Targets.ARRAY_BUFFER,
+ name: ""
+ );
+
+ bufferViews.Add(view);
+ int bufferViewIndex = bufferViews.Count - 1;
+
+ // Create accessor
+ var accessor = new Accessor(
+ bufferView: bufferViewIndex,
+ byteOffset: 0,
+ componentType: ComponentType.FLOAT,
+ count: vertexCount,
+ type: VEC3_STR,
+ max: max,
+ min: min,
+ name: POSITION_STR
+ );
+
+ accessors.Add(accessor);
+ int accessorIndex = accessors.Count - 1;
+
+ // Assign accessor to primitive
+ primitive.attributes.POSITION = accessorIndex;
+
+ return accessorIndex;
}
+
+
const string NORMAL_STR = "NORMALS";
- public static int ExportNormals(int bufferIdx, int byteOffset, GeometryDataObject geomData, GLTFBinaryData bufferData, List bufferViews, List accessors)
+ public static int ExportNormals(
+ GeometryDataObject geomData,
+ GLTFBinaryData bufferData,
+ List bufferViews,
+ List accessors,
+ MeshPrimitive primitive)
{
- for (int i = 0; i < geomData.Normals.Count; i++)
- {
- bufferData.normalBuffer.Add(Convert.ToSingle(geomData.Normals[i]));
- }
-
- // Get max and min for normal data
- float[] normalMinMax = Util.GetVec3MinMax(bufferData.normalBuffer);
-
- // Add a normals (vec3) buffer view
- int elementsPerNormal = 3;
- int bytesPerNormalElement = 4;
- int bytesPerNormal = elementsPerNormal * bytesPerNormalElement;
- var normalsCount = geomData.Normals.Count;
- int numVec3Normals = normalsCount / elementsPerNormal;
- int sizeOfVec3ViewNormals = numVec3Normals * bytesPerNormal;
- GLTFBufferView vec3ViewNormals = new GLTFBufferView(bufferIdx, byteOffset, sizeOfVec3ViewNormals, Targets.ARRAY_BUFFER, string.Empty);
- bufferViews.Add(vec3ViewNormals);
- int vec3ViewNormalsIdx = bufferViews.Count - 1;
-
- // add a normals accessor
- var count = normalsCount / elementsPerNormal;
- var max = new List(3) { normalMinMax[1], normalMinMax[3], normalMinMax[5] };
- var min = new List(3) { normalMinMax[0], normalMinMax[2], normalMinMax[4] };
-
- GLTFAccessor normalsAccessor = new GLTFAccessor(vec3ViewNormalsIdx, 0, ComponentType.FLOAT, count, VEC3_STR, max, min, NORMAL_STR);
- accessors.Add(normalsAccessor);
- bufferData.normalsAccessorIndex = accessors.Count - 1;
- return byteOffset + vec3ViewNormals.byteLength;
+ const string VEC3_STR = "VEC3";
+ const string NORMAL_STR = "NORMAL";
+
+ int normalCount = geomData.Normals.Count;
+ if (normalCount == 0)
+ return -1;
+
+ // Convert normals to float[]
+ float[] normals = geomData.Normals
+ .Select(n => (float)n)
+ .ToArray();
+
+ // Min/Max SOLO para estas normales
+ float[] minMax = Util.GetVec3MinMax(normals);
+
+ var max = new List { minMax[1], minMax[3], minMax[5] };
+ var min = new List { minMax[0], minMax[2], minMax[4] };
+
+ // Append normals al buffer global (float32)
+ int byteOffset = bufferData.AppendFloatArray(normals);
+ int byteLength = normals.Length * sizeof(float);
+
+ // Crear bufferView
+ BufferView view = new BufferView(
+ buffer: 0,
+ byteOffset: byteOffset,
+ byteLength: byteLength,
+ Targets.ARRAY_BUFFER,
+ name: ""
+ );
+
+ bufferViews.Add(view);
+ int viewIdx = bufferViews.Count - 1;
+
+ // Crear accessor
+ int count = normalCount / 3;
+
+ Accessor accessor = new Accessor(
+ bufferView: viewIdx,
+ byteOffset: 0,
+ componentType: ComponentType.FLOAT,
+ count: count,
+ type: VEC3_STR,
+ max: max,
+ min: min,
+ name: NORMAL_STR
+ );
+
+ accessors.Add(accessor);
+ int accessorIdx = accessors.Count - 1;
+
+ // Asignar al primitive
+ primitive.attributes.NORMAL = accessorIdx;
+
+ return accessorIdx;
}
- public static int ExportBatchId(int bufferIdx, int byteOffset, int sizeOfVec3View, int elementsPerVertex, long elementId, GeometryDataObject geomData, GLTFBinaryData bufferData, List bufferViews, List accessors)
+ public static int ExportBatchId(
+ long elementId,
+ GeometryDataObject geomData,
+ GLTFBinaryData bufferData,
+ List bufferViews,
+ List accessors,
+ MeshPrimitive primitive)
{
- for (int i = 0; i < geomData.Vertices.Count; i++)
- {
- bufferData.batchIdBuffer.Add(elementId);
- }
-
- // Get max and min for batchId data
- float[] batchIdMinMax = Util.GetVec3MinMax(bufferData.batchIdBuffer);
-
- // Add a batchId buffer view
- GLTFBufferView batchIdsView = new GLTFBufferView(bufferIdx, byteOffset, sizeOfVec3View, Targets.ARRAY_BUFFER, string.Empty);
- bufferViews.Add(batchIdsView);
- int batchIdsViewIdx = bufferViews.Count - 1;
-
- // add a batchId accessor
- var count = geomData.Vertices.Count / elementsPerVertex;
- var max = new List(3) { batchIdMinMax[1], batchIdMinMax[3], batchIdMinMax[5] };
- var min = new List(3) { batchIdMinMax[0], batchIdMinMax[2], batchIdMinMax[4] };
- GLTFAccessor batchIdAccessor = new GLTFAccessor(batchIdsViewIdx, 0, ComponentType.FLOAT, count, VEC3_STR, max, min, BATCH_ID_STR);
- accessors.Add(batchIdAccessor);
- bufferData.batchIdAccessorIndex = accessors.Count - 1;
- return byteOffset + batchIdsView.byteLength;
+ const string SCALAR_STR = "SCALAR";
+ const string BATCH_ID_STR = "_BATCHID";
+
+ int vertexCount = geomData.Vertices.Count / 3;
+ if (vertexCount == 0)
+ return -1;
+
+ float idValue = (float)elementId;
+ float[] batchIds = Enumerable.Repeat(idValue, vertexCount).ToArray();
+
+ var min = new List { idValue };
+ var max = new List { idValue };
+
+ int byteOffset = bufferData.AppendFloatArray(batchIds);
+ int byteLength = batchIds.Length * sizeof(float);
+
+ BufferView view = new BufferView(
+ buffer: 0,
+ byteOffset: byteOffset,
+ byteLength: byteLength,
+ Targets.ARRAY_BUFFER,
+ name: ""
+ );
+
+ bufferViews.Add(view);
+ int viewIdx = bufferViews.Count - 1;
+
+ Accessor accessor = new Accessor(
+ bufferView: viewIdx,
+ byteOffset: 0,
+ componentType: ComponentType.FLOAT,
+ count: vertexCount,
+ type: SCALAR_STR,
+ max: max,
+ min: min,
+ name: BATCH_ID_STR
+ );
+
+ accessors.Add(accessor);
+ int accessorIdx = accessors.Count - 1;
+
+ primitive.attributes._BATCHID = accessorIdx;
+
+ return accessorIdx;
}
+
public static int ExportUVs(
- int bufferIdx,
- int byteOffset,
- GeometryDataObject geomData,
- GLTFBinaryData bufferData,
- List bufferViews,
- List accessors)
+ GeometryDataObject geomData,
+ GLTFBinaryData bufferData,
+ List bufferViews,
+ List accessors,
+ MeshPrimitive primitive)
{
const string VEC2_STR = "VEC2";
const string TEXCOORD_STR = "TEXCOORD_0";
int uvCount = geomData.Uvs.Count;
+ if (uvCount == 0)
+ return -1;
+
+ float[] uvFloats = new float[uvCount * 2];
+ int ptr = 0;
- // Convert UVs to float buffer (U, V per entry)
foreach (var uv in geomData.Uvs)
{
- bufferData.uvBuffer.Add((float)uv.U);
- bufferData.uvBuffer.Add((float)uv.V);
+ uvFloats[ptr++] = uv.U;
+ uvFloats[ptr++] = uv.V;
}
- int elementsPerUV = 2;
- int bytesPerUVElement = 4;
- int bytesPerUV = elementsPerUV * bytesPerUVElement;
+ List listUvFloats = new List(uvFloats);
+ float[] uvMinMax = Util.GetVec2MinMax(listUvFloats);
+
+ var max = new List { uvMinMax[1], uvMinMax[3] };
+ var min = new List { uvMinMax[0], uvMinMax[2] };
+
+ int byteOffset = bufferData.AppendFloatArray(uvFloats);
+ int byteLength = uvFloats.Length * sizeof(float);
- int sizeOfUVView = uvCount * bytesPerUV;
+ BufferView uvBufferView = new BufferView(
+ buffer: 0,
+ byteOffset: byteOffset,
+ byteLength: byteLength,
+ Targets.ARRAY_BUFFER,
+ name: ""
+ );
- // Create UV buffer view
- GLTFBufferView uvBufferView = new GLTFBufferView(bufferIdx, byteOffset, sizeOfUVView, Targets.ARRAY_BUFFER, string.Empty);
bufferViews.Add(uvBufferView);
- int uvBufferViewIdx = bufferViews.Count - 1;
+ int viewIdx = bufferViews.Count - 1;
- // Min/max for VEC2 accessors (optional, but good practice)
- float[] uvMinMax = Util.GetVec2MinMax(bufferData.uvBuffer);
- var max = new List { uvMinMax[1], uvMinMax[3] };
- var min = new List { uvMinMax[0], uvMinMax[2] };
+ Accessor accessor = new Accessor(
+ bufferView: viewIdx,
+ byteOffset: 0,
+ componentType: ComponentType.FLOAT,
+ count: uvCount,
+ type: VEC2_STR,
+ max: max,
+ min: min,
+ name: TEXCOORD_STR
+ );
+
+ accessors.Add(accessor);
+ int accessorIdx = accessors.Count - 1;
- // Create UV accessor
- GLTFAccessor uvAccessor = new GLTFAccessor(
- uvBufferViewIdx,
- 0,
- ComponentType.FLOAT,
- uvCount,
- VEC2_STR,
- max,
- min,
- TEXCOORD_STR);
-
- accessors.Add(uvAccessor);
- bufferData.uvAccessorIndex = accessors.Count - 1;
-
- return byteOffset + uvBufferView.byteLength;
+ primitive.attributes.TEXCOORD_0 = accessorIdx;
+
+ return accessorIdx;
}
- public static int ExportImageBuffer(
- int bufferIdx,
- int byteOffset,
- GLTFMaterial material,
- List images,
- List textures,
- GLTFBinaryData bufferData,
- List bufferViews)
+ public static void ExportImageBuffer(
+ List images,
+ List bufferViews,
+ GLTFBinaryData bufferData)
{
- if (material.EmbeddedTexturePath == null)
- {
- return byteOffset;
- }
-
- if (material.pbrMetallicRoughness.baseColorTexture.index == -1)
- {
- byte[] imageBytes = File.ReadAllBytes(material.EmbeddedTexturePath);
- (string , ImageFormat) mimeType = BitmapsUtils.GetMimeType(material.EmbeddedTexturePath);
-
- byte[] blendedBytes = BitmapsUtils.BlendImageWithColor(imageBytes, material.Fadevalue,
- material.BaseColor, mimeType.Item2, material.TintColour);
-
- if (blendedBytes != null)
- {
- if (bufferData.byteData == null)
- {
- bufferData.byteData = blendedBytes;
- }
- else
- {
- byte[] combined = new byte[bufferData.byteData.Length + blendedBytes.Length];
- Buffer.BlockCopy(bufferData.byteData, 0, combined, 0, bufferData.byteData.Length);
- Buffer.BlockCopy(blendedBytes, 0, combined, bufferData.byteData.Length, blendedBytes.Length);
- bufferData.byteData = combined;
- }
- }
-
- int currentLenght = blendedBytes.Length;
- int alignment = 4;
- int padding = (alignment - (currentLenght % alignment)) % alignment;
-
- if (padding != 0)
- {
- currentLenght = currentLenght + padding;
-
- byte[] newArray = bufferData.byteData.Concat(new byte[padding]).ToArray();
- bufferData.byteData = newArray;
- }
-
- GLTFBufferView ImageBufferView = new GLTFBufferView(bufferIdx, byteOffset, currentLenght, Targets.NONE, string.Empty);
-
- bufferViews.Add(ImageBufferView);
- int bufferViewIndex = bufferViews.Count - 1;
-
- var image = new GLTFImage
- {
- bufferView = bufferViewIndex,
- mimeType = mimeType.Item1
- };
-
- images.Add(image);
- int imageIndex = images.Count - 1;
-
- var texture = new GLTFTexture
- {
- source = imageIndex
- };
- textures.Add(texture);
- int textureIndex = textures.Count - 1;
- material.pbrMetallicRoughness.baseColorTexture.index = textureIndex;
- return byteOffset + ImageBufferView.byteLength;
- }
- else
+ foreach (var baseImage in images)
{
- return byteOffset;
+ byte[] imgBytes = baseImage.imageData;
+ if (imgBytes == null || imgBytes.Length == 0)
+ continue;
+
+ int byteOffset = bufferData.GetCurrentByteOffset();
+ int byteLength = bufferData.Append(imgBytes);
+
+ BufferView imgView = new BufferView(
+ buffer: 0,
+ byteOffset: byteOffset,
+ byteLength: byteLength,
+ Targets.NONE,
+ name: ""
+ );
+
+ bufferViews.Add(imgView);
+ int viewIdx = bufferViews.Count - 1;
+
+ baseImage.bufferView = viewIdx;
+ baseImage.uri = null;
}
}
}
diff --git a/Common_glTF_Exporter/Utils/MaterialUtils.cs b/Common_glTF_Exporter/Utils/MaterialUtils.cs
index 0a8e60a..d559e4c 100644
--- a/Common_glTF_Exporter/Utils/MaterialUtils.cs
+++ b/Common_glTF_Exporter/Utils/MaterialUtils.cs
@@ -2,19 +2,23 @@
{
using Autodesk.Revit.DB;
using Common_glTF_Exporter.Core;
+ using Common_glTF_Exporter.Model;
using Common_glTF_Exporter.Windows.MainWindow;
+ using glTF.Manipulator.GenericSchema;
+ using glTF.Manipulator.Schema;
+ using glTF.Manipulator.Utils;
using Revit_glTF_Exporter;
using System.Collections.Generic;
public class MaterialUtils
{
- public static Material GetMeshMaterial(Document doc, Mesh mesh)
+ public static Autodesk.Revit.DB.Material GetMeshMaterial(Document doc, Autodesk.Revit.DB.Mesh mesh)
{
ElementId materialId = mesh.MaterialElementId;
if (materialId != null)
{
- return doc.GetElement(materialId) as Material;
+ return doc.GetElement(materialId) as Autodesk.Revit.DB.Material;
}
else
{
@@ -22,29 +26,27 @@ public static Material GetMeshMaterial(Document doc, Mesh mesh)
}
}
- public static GLTFMaterial GetGltfMeshMaterial(Document doc, Preferences preferences, Mesh mesh, IndexedDictionary materials, bool doubleSided)
+ public static BaseMaterial GetGltfMeshMaterial(Document doc, Preferences preferences, Autodesk.Revit.DB.Mesh mesh, IndexedDictionary materials, bool doubleSided)
{
- GLTFMaterial gl_mat = new GLTFMaterial();
+ BaseMaterial gl_mat = new BaseMaterial();
- Material material = GetMeshMaterial(doc, mesh);
+ Autodesk.Revit.DB.Material material = GetMeshMaterial(doc, mesh);
if (preferences.materials == MaterialsEnum.materials || preferences.materials == MaterialsEnum.textures)
{
if (material == null)
{
- gl_mat = GLTFExportUtils.GetGLTFMaterial(materials, 1, doubleSided);
+ gl_mat = GLTFExportUtils.GetGLTFMaterial(materials);
}
else
{
gl_mat.doubleSided = doubleSided;
float opacity = 1 - (float)material.Transparency;
gl_mat.name = material.Name;
- GLTFPBR pbr = new GLTFPBR();
- pbr.baseColorFactor = new List(4) { material.Color.Red / 255f, material.Color.Green / 255f, material.Color.Blue / 255f, opacity };
- pbr.metallicFactor = 0f;
- pbr.roughnessFactor = 1f;
- gl_mat.pbrMetallicRoughness = pbr;
- gl_mat.UniqueId = material.UniqueId;
+
+ gl_mat.baseColorFactor = new List(4) { material.Color.Red / 255f, material.Color.Green / 255f, material.Color.Blue / 255f, opacity };
+ gl_mat.metallicFactor = 0f;
+ gl_mat.roughnessFactor = 1f;
}
}
diff --git a/Common_glTF_Exporter/Utils/glTFExportUtils.cs b/Common_glTF_Exporter/Utils/glTFExportUtils.cs
index 476bcf8..e170f4e 100644
--- a/Common_glTF_Exporter/Utils/glTFExportUtils.cs
+++ b/Common_glTF_Exporter/Utils/glTFExportUtils.cs
@@ -1,47 +1,40 @@
- namespace Common_glTF_Exporter.Utils
- {
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using Autodesk.Revit.DB;
- using Common_glTF_Exporter.Core;
- using Common_glTF_Exporter.Model;
- using Common_glTF_Exporter.Windows.MainWindow;
- using Revit_glTF_Exporter;
-
- public class GLTFExportUtils
+namespace Common_glTF_Exporter.Utils
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using Autodesk.Revit.DB;
+ using Common_glTF_Exporter.Core;
+ using Common_glTF_Exporter.Model;
+ using Common_glTF_Exporter.Windows.MainWindow;
+ using glTF.Manipulator.GenericSchema;
+ using glTF.Manipulator.Schema;
+ using glTF.Manipulator.Utils;
+ using Revit_glTF_Exporter;
+ using Buffer = glTF.Manipulator.Schema.Buffer;
+ public class GLTFExportUtils
{
const int DEF_COLOR = 250;
const string DEF_MATERIAL_NAME = "default";
- const string DEF_UNIQUEL_ID = "8a3c94b3-d9e2-4e57-9189-f9bb6a9a54a4";
+ public const string DEF_UNIQUEL_ID = "8a3c94b3-d9e2-4e57-9189-f9bb6a9a54a4";
- public static GLTFMaterial GetGLTFMaterial(IndexedDictionary gltfMaterials, double opacity, bool doubleSided)
+ public static BaseMaterial GetGLTFMaterial(IndexedDictionary Materials)
{
-
- if (gltfMaterials.Dict.ContainsKey(DEF_UNIQUEL_ID))
- {
- return gltfMaterials.GetElement(DEF_UNIQUEL_ID);
- }
- else
- {
- return (CreateDefaultGLTFMaterial((int)opacity, doubleSided));
- }
+ return Materials.GetElement(DEF_UNIQUEL_ID);
}
- public static GLTFMaterial CreateDefaultGLTFMaterial(int materialOpacity, bool doubleSided)
+ public static BaseMaterial CreateDefaultGLTFMaterial(int materialOpacity, bool doubleSided)
{
- GLTFMaterial gl_mat = new GLTFMaterial();
- gl_mat.doubleSided = doubleSided;
+ BaseMaterial baseMaterial = new BaseMaterial();
+ baseMaterial.doubleSided = doubleSided;
float opacity = 1 - (float)materialOpacity;
- gl_mat.name = DEF_MATERIAL_NAME;
- GLTFPBR pbr = new GLTFPBR();
- pbr.baseColorFactor = new List