예제 #1
0
        /// <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.parameters        = Util.GetElementParameters(e, true);
                extras.elementId         = e.Id.IntegerValue;
                extras.elementCategory   = e.Category.Name;
                extras.dependentElements = Util.GetDependentElements(e);
                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);
        }
예제 #2
0
        /// <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.parameters     = Util.GetElementParameters(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);
                            }
                            //foreach (var normal in bin.normalBuffer)
                            //{
                            //    writer.Write((float)normal);
                            //}
                            foreach (var index in bin.indexBuffer)
                            {
                                writer.Write((int)index);
                            }
                            foreach (var batchId in bin.batchIdBuffer)
                            {
                                writer.Write((float)batchId);
                            }
                        }
                    }
                }
            }

            // 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);
                            }
                            //foreach (var normal in bin.normalBuffer)
                            //{
                            //    writer.Write((float)normal);
                            //}
                            foreach (var index in bin.indexBuffer)
                            {
                                writer.Write((int)index);
                            }
                            foreach (var batchId in bin.batchIdBuffer)
                            {
                                writer.Write((float)batchId);
                            }
                        }
                    }
                }
            }
        }