/// <summary> /// Runs once at beginning of export. Sets up the root node /// and scene. /// </summary> /// <returns></returns> public bool Start() { Debug.WriteLine("Starting..."); _transformStack.Push(Transform.Identity); float scale = 1f; // could play with this to match units in a different viewer. rootNode = new glTFNode(); rootNode.name = "rootNode"; //rootNode.matrix = new List<float>() //{ // scale, 0, 0, 0, // 0, scale, 0, 0, // 0, 0, scale, 0, // 0, 0, 0, scale //}; rootNode.children = new List <int>(); Nodes.AddOrUpdateCurrent("rootNode", rootNode); glTFScene defaultScene = new glTFScene(); defaultScene.nodes.Add(0); Scenes.Add(defaultScene); return(true); }
public glTFNode ToGLTFNode() { glTFNode node = new glTFNode(); node.name = this.name; node.mesh = this.mesh; node.matrix = this.matrix; node.extras = this.extras; node.children = this.children; return(node); }
/// <summary> /// Runs once for each element, we create a new glTFNode and glTF Mesh /// keyed to the elements uuid, and reset the "_current" variables. /// </summary> /// <param name="elementId">ElementId of Element being processed</param> /// <returns></returns> public RenderNodeAction OnElementBegin(ElementId elementId) { Debug.WriteLine(" OnElementBegin"); Element e = _doc.GetElement(elementId); if (Nodes.Contains(e.UniqueId)) { // Duplicate element, skip adding. Debug.WriteLine(" Duplicate Element!"); _skipElementFlag = true; return(RenderNodeAction.Skip); } // create a new node for the element glTFNode newNode = new glTFNode(); newNode.name = Util.ElementDescription(e); //newNode.matrix = new List<float>() { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 }; if (_exportProperties) { // get the extras for this element glTFExtras extras = new glTFExtras(); extras.UniqueId = e.UniqueId; extras.Properties = Util.GetElementProperties(e, true); newNode.extras = extras; Nodes.AddOrUpdateCurrent(e.UniqueId, newNode); // add the index of this node to our root node children array rootNode.children.Add(Nodes.CurrentIndex); } // Reset _currentGeometry for new element _currentGeometry = new IndexedDictionary <GeometryData>(); _currentVertices = new IndexedDictionary <VertexLookupInt>(); return(RenderNodeAction.Proceed); }
/// <summary> /// Runs once at end of export. Serializes the gltf /// properties and wites out the *.gltf and *.bin files. /// </summary> public void Finish() { Debug.WriteLine("Finishing..."); glTFContainer container = manager.Finish(); if (_cfgs.IncludeNonStdElements) { // TODO: [RM] Standardize what non glTF spec elements will go into // this "BIM glTF superset" and write a spec for it. Gridlines below // are an example. // Add gridlines as gltf nodes in the format: // Origin {Vec3<double>}, Direction {Vec3<double>}, Length {double} FilteredElementCollector col = new FilteredElementCollector(_doc) .OfClass(typeof(Grid)); var grids = col.ToElements(); foreach (Grid g in grids) { Line l = g.Curve as Line; var origin = l.Origin; var direction = l.Direction; var length = l.Length; var xtras = new glTFExtras(); var grid = new GridParameters(); grid.origin = new List <double>() { origin.X, origin.Y, origin.Z }; grid.direction = new List <double>() { direction.X, direction.Y, direction.Z }; grid.length = length; xtras.GridParameters = grid; xtras.UniqueId = g.UniqueId; xtras.Properties = Util.GetElementProperties(g, true); var gridNode = new glTFNode(); gridNode.name = g.Name; gridNode.extras = xtras; container.glTF.nodes.Add(gridNode); container.glTF.nodes[0].children.Add(container.glTF.nodes.Count - 1); } } if (_cfgs.SingleBinary) { int bytePosition = 0; int currentBuffer = 0; foreach (var view in container.glTF.bufferViews) { if (view.buffer == 0) { bytePosition += view.byteLength; continue; } if (view.buffer != currentBuffer) { view.buffer = 0; view.byteOffset = bytePosition; bytePosition += view.byteLength; } } glTFBuffer buffer = new glTFBuffer(); buffer.uri = _filename + ".bin"; buffer.byteLength = bytePosition; container.glTF.buffers.Clear(); container.glTF.buffers.Add(buffer); using (FileStream f = File.Create(Path.Combine(_directory, buffer.uri))) { using (BinaryWriter writer = new BinaryWriter(f)) { foreach (var bin in container.binaries) { foreach (var coord in bin.contents.vertexBuffer) { writer.Write((float)coord); } // TODO: add writer for normals buffer foreach (var index in bin.contents.indexBuffer) { writer.Write((int)index); } } } } } else { // Write the *.bin files foreach (var bin in container.binaries) { using (FileStream f = File.Create(Path.Combine(_directory, bin.name))) { using (BinaryWriter writer = new BinaryWriter(f)) { foreach (var coord in bin.contents.vertexBuffer) { writer.Write((float)coord); } // TODO: add writer for normals buffer foreach (var index in bin.contents.indexBuffer) { writer.Write((int)index); } } } } } // Write the *.gltf file string serializedModel = JsonConvert.SerializeObject(container.glTF, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); File.WriteAllText(Path.Combine(_directory, _filename + ".gltf"), serializedModel); }
/// <summary> /// Runs once at end of export. Serializes the gltf /// properties and wites out the *.gltf and *.bin files. /// </summary> public void Finish() { Debug.WriteLine("Finishing..."); gltfContainer = manager.Finish(); if (_cfgs.IncludeNonStdElements) { // TODO: [RM] Standardize what non glTF spec elements will go into // this "BIM glTF superset" and write a spec for it. Gridlines below // are an example. // Add gridlines as gltf nodes in the format: // Origin {Vec3<double>}, Direction {Vec3<double>}, Length {double} FilteredElementCollector col = new FilteredElementCollector(_doc) .OfClass(typeof(Grid)); var grids = col.ToElements(); foreach (Grid g in grids) { Line l = g.Curve as Line; var origin = l.Origin; var direction = l.Direction; var length = l.Length; var xtras = new glTFExtras(); var grid = new GridParameters(); grid.origin = new List <double>() { origin.X, origin.Y, origin.Z }; grid.direction = new List <double>() { direction.X, direction.Y, direction.Z }; grid.length = length; xtras.GridParameters = grid; xtras.UniqueId = g.UniqueId; xtras.Properties = Util.GetElementProperties(g, true); var gridNode = new glTFNode(); gridNode.name = g.Name; gridNode.extras = xtras; gltfContainer.glTF.nodes.Add(gridNode); gltfContainer.glTF.nodes[0].children.Add(gltfContainer.glTF.nodes.Count - 1); } } if (_cfgs.SingleBinary) { int bytePosition = 0; int currentBuffer = 0; foreach (var view in gltfContainer.glTF.bufferViews) { if (view.buffer == 0) { bytePosition += view.byteLength; continue; } if (view.buffer != currentBuffer) { view.buffer = 0; view.byteOffset = bytePosition; bytePosition += view.byteLength; } } glTFBuffer buffer = new glTFBuffer(); buffer.uri = _filename + ".bin"; buffer.byteLength = bytePosition; gltfContainer.glTF.buffers.Clear(); gltfContainer.glTF.buffers.Add(buffer); using (FileStream f = File.Create(Path.Combine(_directory, buffer.uri))) { using (BinaryWriter writer = new BinaryWriter(f)) { foreach (var bin in gltfContainer.binaries) { foreach (var coord in bin.contents.vertexBuffer) { writer.Write((float)coord); } // TODO: add writer for normals buffer foreach (var index in bin.contents.indexBuffer) { writer.Write((int)index); } } } } } else { // Write the *.bin files foreach (var bin in gltfContainer.binaries) { using (FileStream f = File.Create(Path.Combine(_directory, bin.name))) { using (BinaryWriter writer = new BinaryWriter(f)) { foreach (var coord in bin.contents.vertexBuffer) { writer.Write((float)coord); } // TODO: add writer for normals buffer foreach (var index in bin.contents.indexBuffer) { writer.Write((int)index); } } } } } try { // Write the *.gltf file string pgltf = Path.Combine(_directory, _filename + ".gltf"); string serializedModel = JsonConvert.SerializeObject(gltfContainer.glTF, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); File.WriteAllText(pgltf, serializedModel); } catch (Exception ex) { MessageBox.Show(ex.GetType().Name + "\n" + ex.Message); } // FIXME convert to glb. // problem: can't load file or assembly System.Runtime.CompilerServices.Unsafe v4.0.6 // see possible cause here https://stackoverflow.com/a/62769681 // var mglb = SharpGLTF.Schema2.ModelRoot.Load(pgltf); // mglb.SaveGLB(Path.Combine(_directory, _filename + ".glb")); }
/// <summary> /// Runs once at end of export. Serializes the gltf /// properties and wites out the *.gltf and *.bin files. /// </summary> public void Finish() { Debug.WriteLine("Finishing..."); // TODO: [RM] Standardize what non glTF spec elements will go into // this "BIM glTF superset" and write a spec for it. Gridlines below // are an example. // Add gridlines as gltf nodes in the format: // Origin {Vec3<double>}, Direction {Vec3<double>}, Length {double} FilteredElementCollector col = new FilteredElementCollector(_doc) .OfClass(typeof(Grid)); var grids = col.ToElements(); foreach (Grid g in grids) { Line l = g.Curve as Line; var origin = l.Origin; var direction = l.Direction; var length = l.Length; var xtras = new glTFExtras(); var grid = new GridParameters(); grid.origin = new List <double>() { origin.X, origin.Y, origin.Z }; grid.direction = new List <double>() { direction.X, direction.Y, direction.Z }; grid.length = length; xtras.GridParameters = grid; xtras.UniqueId = g.UniqueId; xtras.Properties = Util.GetElementProperties(g, true); var gridNode = new glTFNode(); gridNode.name = g.Name; gridNode.extras = xtras; Nodes.AddOrUpdateCurrent(g.UniqueId, gridNode); rootNode.children.Add(Nodes.CurrentIndex); } if (_singleBinary) { int bytePosition = 0; int currentBuffer = 0; foreach (var view in BufferViews) { if (view.buffer == 0) { bytePosition += view.byteLength; continue; } if (view.buffer != currentBuffer) { view.buffer = 0; view.byteOffset = bytePosition; bytePosition += view.byteLength; } } glTFBuffer buffer = new glTFBuffer(); buffer.uri = "monobuffer.bin"; buffer.byteLength = bytePosition; Buffers.Clear(); Buffers.Add(buffer); using (FileStream f = File.Create(_directory + "monobuffer.bin")) { using (BinaryWriter writer = new BinaryWriter(f)) { foreach (var bin in binaryFileData) { foreach (var coord in bin.vertexBuffer) { writer.Write((float)coord); } // TODO: add writer for normals buffer foreach (var index in bin.indexBuffer) { writer.Write((int)index); } } } } } // Package the properties into a serializable container glTF model = new glTF(); model.asset = new glTFVersion(); model.scenes = Scenes; model.nodes = Nodes.List; model.meshes = Meshes.List; model.materials = Materials.List; model.buffers = Buffers; model.bufferViews = BufferViews; model.accessors = Accessors; // Write the *.gltf file string serializedModel = JsonConvert.SerializeObject(model, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); File.WriteAllText(_filename, serializedModel); if (!_singleBinary) { // Write the *.bin files foreach (var bin in binaryFileData) { using (FileStream f = File.Create(_directory + bin.name)) { using (BinaryWriter writer = new BinaryWriter(f)) { foreach (var coord in bin.vertexBuffer) { writer.Write((float)coord); } // TODO: add writer for normals buffer foreach (var index in bin.indexBuffer) { writer.Write((int)index); } } } } } }