예제 #1
0
    public static GameObject Update(this GameObject go, Element element, UnityEngine.Material material)
    {
        var goMeshFilter = go.GetComponent <MeshFilter>();
        var goRenderer   = go.GetComponent <MeshRenderer>();

        goRenderer.material = material;
        var goMesh = goMeshFilter.mesh;

        goMesh.Clear();
        // var o = element.Transform.Origin.ToUnityVector3();
        var verts = new List <UnityEngine.Vector3>();
        var tris  = new List <int>();

        if (element is IGeometry3D)
        {
            var tess = (IGeometry3D)element;
            var mesh = new Elements.Geometry.Mesh();
            tess.Geometry[0].Tessellate(ref mesh);
            verts.AddRange(mesh.Vertices.ToArray().ToUnityVertices(element.Transform));
            tris.AddRange(mesh.Indices.Select(idx => (int)idx));
        }

        goMesh.vertices  = verts.ToArray();
        goMesh.triangles = tris.ToArray();
        goMesh.RecalculateNormals();

        return(go);
    }
예제 #2
0
    public static GameObject ToGameObject(this Element element, GameObject parent, UnityEngine.Material material)
    {
        var go           = new GameObject($"hypar_{element.Id}");
        var goMeshFilter = go.AddComponent <MeshFilter>();
        var goRenderer   = go.AddComponent <MeshRenderer>();

        goRenderer.material = material;
        var goMesh = new UnityEngine.Mesh();

        goMeshFilter.mesh = goMesh;

        go.transform.SetParent(parent.transform, false);

        var verts = new List <UnityEngine.Vector3>();
        var tris  = new List <int>();

        if (element is IGeometry3D)
        {
            var geo  = (IGeometry3D)element;
            var mesh = new Elements.Geometry.Mesh();
            geo.Geometry[0].Tessellate(ref mesh);
            verts.AddRange(mesh.Vertices.ToArray().ToUnityVertices(element.Transform));
            tris.AddRange(mesh.Indices.Select(idx => (int)idx));
        }

        goMesh.vertices  = verts.ToArray();
        goMesh.triangles = tris.ToArray();
        goMesh.RecalculateNormals();

        return(go);
    }
예제 #3
0
        private void GetRenderDataForElement(IElement e, Gltf gltf, Dictionary <string, int> materials, List <Vector3> lines)
        {
            if (e is IGeometry3D)
            {
                var geo = e as IGeometry3D;

                Elements.Geometry.Mesh mesh = null;

                foreach (var solid in geo.Geometry)
                {
                    foreach (var edge in solid.Edges.Values)
                    {
                        if (e.Transform != null)
                        {
                            lines.AddRange(new[] { e.Transform.OfVector(edge.Left.Vertex.Point), e.Transform.OfVector(edge.Right.Vertex.Point) });
                        }
                        else
                        {
                            lines.AddRange(new[] { edge.Left.Vertex.Point, edge.Right.Vertex.Point });
                        }
                    }

                    mesh = new Elements.Geometry.Mesh();
                    solid.Tessellate(ref mesh);
                    gltf.AddTriangleMesh(e.Id + "_mesh", _buffer, mesh.Vertices.ToArray(), mesh.Normals.ToArray(),
                                         mesh.Indices.ToArray(), mesh.VMin, mesh.VMax, mesh.NMin, mesh.NMax,
                                         mesh.IMin, mesh.IMax, materials[solid.Material.Name], null, e.Transform);
                }
            }

            if (e is IAggregateElement)
            {
                var ae = (IAggregateElement)e;

                if (ae.Elements.Count > 0)
                {
                    foreach (var esub in ae.Elements)
                    {
                        GetRenderDataForElement(esub, gltf, materials, lines);
                    }
                }
            }
        }
예제 #4
0
        public static Elements.Geometry.Mesh ToMesh(this MeshData vMesh)
        {
            var mesh     = new Elements.Geometry.Mesh();
            var vertices = new List <Vertex>();

            for (int i = 0; i < vMesh.points.length; i++)
            {
                var pt     = (vMesh.points[i] as Array <double>).ToVector3();
                var normal = (vMesh.normals[i] as Array <double>).ToVector3();
                var vertex = new Vertex(pt, normal);
                vertices.Add(vertex);
                mesh.AddVertex(vertex);
            }
            Console.WriteLine(vertices.Count);
            for (int i = 0; i < vMesh.faces.length; i++)
            {
                var face = vMesh.faces[i] as Array <int>;
                mesh.AddTriangle(vertices[face[2]], vertices[face[1]], vertices[face[0]]);
            }
            return(mesh);
        }
예제 #5
0
        /// <summary>
        /// Generates a Roof from a DXF Polyline and supplied elevation and thickness values.
        /// </summary>
        /// <param name="model">The input model.</param>
        /// <param name="input">The arguments to the execution.</param>
        /// <returns>A RoofByDXFOutputs instance containing computed results and the model with any new elements.</returns>
        public static RoofByDXFOutputs Execute(Dictionary <string, Model> inputModels, RoofByDXFInputs input)
        {
            DxfFile dxfFile;

            using (FileStream fs = new FileStream(input.DXF.LocalFilePath, FileMode.Open))
            {
                dxfFile = DxfFile.Load(fs);
            }
            var polygons = new List <Polygon>();

            foreach (DxfEntity entity in dxfFile.Entities)
            {
                if (entity.EntityType != DxfEntityType.LwPolyline)
                {
                    continue;
                }
                var pline = (DxfLwPolyline)entity;
                if (pline.IsClosed == false)
                {
                    continue;
                }
                var vertices = pline.Vertices.ToList();
                var verts    = new List <Vector3>();
                vertices.ForEach(v => verts.Add(new Vector3(v.X, v.Y)));
                polygons.Add(new Polygon(verts));
            }
            if (polygons.Count == 0)
            {
                throw new ArgumentException("No LWPolylines found in DXF.");
            }
            var highPoint = input.RoofElevation + input.RoofThickness;

            polygons = polygons.OrderByDescending(p => Math.Abs(p.Area())).ToList();
            var polygon = polygons.First().IsClockWise() ? polygons.First().Reversed() : polygons.First();

            polygon = polygon.TransformedPolygon(new Transform(0.0, 0.0, highPoint));
            var underBoundary = polygon.TransformedPolygon(new Transform(0.0, 0.0, input.RoofThickness * -1.0));
            var ePoints       = polygon.Vertices.ToList();
            var uPoints       = underBoundary.Vertices.ToList();

            var topSide   = polygon.ToMesh(true);
            var underSide = underBoundary.ToMesh(false);

            var sideTriangles = new List <Elements.Geometry.Triangle>();

            for (var i = 0; i < ePoints.Count; i++)
            {
                sideTriangles.Add(new Elements.Geometry.Triangle(new Vertex(ePoints[i]),
                                                                 new Vertex(uPoints[i]),
                                                                 new Vertex(uPoints[(i + 1) % uPoints.Count])));
                sideTriangles.Add(new Elements.Geometry.Triangle(new Vertex(ePoints[i]),
                                                                 new Vertex(uPoints[(i + 1) % uPoints.Count]),
                                                                 new Vertex(ePoints[(i + 1) % ePoints.Count])));
            }


            // Create an aggregated list of Triangles representing the Roof envelope.
            var envTriangles = new List <Elements.Geometry.Triangle>();

            topSide.Triangles.ForEach(t => envTriangles.Add(t));
            underSide.Triangles.ForEach(t => envTriangles.Add(t));
            sideTriangles.ForEach(t => envTriangles.Add(t));

            // Create an aggregated list of Vertices representing the Roof envelope.
            var enVertices = new List <Vertex>();

            envTriangles.ForEach(t => enVertices.AddRange(t.Vertices));

            // Construct the roof envelope in Elements.Geometry.mesh form.
            var Envelope = new Elements.Geometry.Mesh();

            envTriangles.ForEach(t => Envelope.AddTriangle(t));
            enVertices.ForEach(v => Envelope.AddVertex(v));
            Envelope.ComputeNormals();

            // Construct serializable topside mesh
            var triangles = new List <triangles>();
            var indices   = new List <vertices>();
            var tsIV      = topSide.ToIndexedVertices();

            tsIV.triangles.ForEach(t => triangles.Add(new triangles(t)));
            tsIV.vertices.ForEach(v => indices.Add(new vertices(v.index, v.isBoundary, v.position)));
            var topside = new Elements.Mesh(triangles, indices);


            // Construct serializable underside mesh
            triangles.Clear();
            indices.Clear();
            var usIV = underSide.ToIndexedVertices();

            usIV.triangles.ForEach(t => triangles.Add(new triangles(t)));
            usIV.vertices.ForEach(v => indices.Add(new vertices(v.index, v.isBoundary, v.position)));
            var underside = new Elements.Mesh(triangles, indices);

            // Construct serializable envelope mesh
            triangles.Clear();
            indices.Clear();
            var enIV = Envelope.ToIndexedVertices();

            enIV.triangles.ForEach(t => triangles.Add(new triangles(t)));
            enIV.vertices.ForEach(v => indices.Add(new vertices(v.index, v.isBoundary, v.position)));
            var envelope = new Elements.Mesh(triangles, indices);

            var roof =
                new Roof(
                    envelope,
                    topside,
                    underside,
                    underBoundary,
                    input.RoofElevation,
                    highPoint,
                    input.RoofThickness,
                    polygon.Area(),
                    new Transform(),
                    BuiltInMaterials.Concrete,
                    null, false, Guid.NewGuid(), "Roof");
            var output = new RoofByDXFOutputs(polygon.Area());

            output.Model.AddElement(new MeshElement(Envelope, BuiltInMaterials.Concrete));
            output.Model.AddElement(roof);
            return(output);
        }
예제 #6
0
        internal static void ToGlb(this Solid solid, string path)
        {
            var gltf  = new Gltf();
            var asset = new Asset();

            asset.Version   = "2.0";
            asset.Generator = "hypar-gltf";

            gltf.Asset = asset;

            var root = new Node();

            root.Translation = new[] { 0.0f, 0.0f, 0.0f };
            root.Scale       = new[] { 1.0f, 1.0f, 1.0f };

            // Set Z up by rotating -90d around the X Axis
            var q = new Quaternion(new Vector3(1, 0, 0), -Math.PI / 2);

            root.Rotation = new[] {
                (float)q.X, (float)q.Y, (float)q.Z, (float)q.W
            };

            gltf.Nodes = new[] { root };

            gltf.Scene = 0;
            var scene = new Scene();

            scene.Nodes = new[] { 0 };
            gltf.Scenes = new[] { scene };

            gltf.ExtensionsUsed = new[] { "KHR_materials_pbrSpecularGlossiness" };

            var materials = gltf.AddMaterials(new[] { BuiltInMaterials.Default, BuiltInMaterials.Edges, BuiltInMaterials.EdgesHighlighted });

            var buffer = new List <byte>();
            var mesh   = new Elements.Geometry.Mesh();

            solid.Tessellate(ref mesh);

            gltf.AddTriangleMesh("mesh", buffer, mesh.Vertices.ToArray(), mesh.Normals.ToArray(),
                                 mesh.Indices.ToArray(), mesh.VertexColors.ToArray(),
                                 mesh.VMin, mesh.VMax, mesh.NMin, mesh.NMax, mesh.CMin, mesh.CMax,
                                 mesh.IMin, mesh.IMax, materials[BuiltInMaterials.Default.Name], null, null);

            var edgeCount           = 0;
            var vertices            = new List <Vector3>();
            var verticesHighlighted = new List <Vector3>();

            foreach (var e in solid.Edges.Values)
            {
                if (e.Left.Loop == null || e.Right.Loop == null)
                {
                    verticesHighlighted.AddRange(new[] { e.Left.Vertex.Point, e.Right.Vertex.Point });
                }
                else
                {
                    vertices.AddRange(new[] { e.Left.Vertex.Point, e.Right.Vertex.Point });
                }

                edgeCount++;
            }

            if (vertices.Count > 0)
            {
                // Draw standard edges
                var vBuff  = vertices.ToArray().ToArray();
                var vCount = vertices.Count;
                // var indices = Enumerable.Range(0, vCount).Select(i => (ushort)i).ToArray();
                var indices = new List <ushort>();
                for (var i = 0; i < vertices.Count; i += 2)
                {
                    indices.Add((ushort)i);
                    indices.Add((ushort)(i + 1));
                }
                var bbox = new BBox3(vertices.ToArray());
                gltf.AddLineLoop($"edge_{edgeCount}", buffer, vBuff, indices.ToArray(), bbox.Min.ToArray(), bbox.Max.ToArray(), 0, (ushort)(vCount - 1), materials[BuiltInMaterials.Edges.Name], MeshPrimitive.ModeEnum.LINES, null);
            }

            if (verticesHighlighted.Count > 0)
            {
                // Draw highlighted edges
                var vBuff   = vertices.ToArray().ToArray();
                var vCount  = vertices.Count;
                var indices = new List <ushort>();
                for (var i = 0; i < vertices.Count; i += 2)
                {
                    indices.Add((ushort)i);
                    indices.Add((ushort)(i + 1));
                }
                var bbox = new BBox3(vertices.ToArray());
                gltf.AddLineLoop($"edge_{edgeCount}", buffer, vBuff, indices.ToArray(), bbox.Min.ToArray(), bbox.Max.ToArray(), 0, (ushort)(vCount - 1), materials[BuiltInMaterials.EdgesHighlighted.Name], MeshPrimitive.ModeEnum.LINES, null);
            }

            var buff = new glTFLoader.Schema.Buffer();

            buff.ByteLength = buffer.Count;
            gltf.Buffers    = new[] { buff };

            if (File.Exists(path))
            {
                File.Delete(path);
            }

            gltf.SaveBinaryModel(buffer.ToArray(), path);
        }
예제 #7
0
        private static void GetRenderDataForElement(IElement e, Gltf gltf,
                                                    Dictionary <string, int> materials, List <Vector3> lines, List <byte> buffer)
        {
            if (e is IGeometry3D)
            {
                var geo = e as IGeometry3D;

                Elements.Geometry.Mesh mesh = null;

                foreach (var solid in geo.Geometry)
                {
                    foreach (var edge in solid.Edges.Values)
                    {
                        if (e.Transform != null)
                        {
                            lines.AddRange(new[] { e.Transform.OfPoint(edge.Left.Vertex.Point), e.Transform.OfPoint(edge.Right.Vertex.Point) });
                        }
                        else
                        {
                            lines.AddRange(new[] { edge.Left.Vertex.Point, edge.Right.Vertex.Point });
                        }
                    }

                    mesh = new Elements.Geometry.Mesh();
                    solid.Tessellate(ref mesh);

                    double[] vertexBuffer;
                    double[] normalBuffer;
                    ushort[] indexBuffer;
                    float[]  colorBuffer;
                    double[] vmin; double[] vmax;
                    double[] nmin; double[] nmax;
                    float[]  cmin; float[] cmax;
                    ushort   imin; ushort imax;

                    mesh.GetBuffers(out vertexBuffer, out indexBuffer, out normalBuffer, out colorBuffer,
                                    out vmax, out vmin, out nmin, out nmax, out cmin,
                                    out cmax, out imin, out imax);

                    gltf.AddTriangleMesh(e.Id + "_mesh", buffer, vertexBuffer, normalBuffer,
                                         indexBuffer, colorBuffer, vmin, vmax, nmin, nmax,
                                         imin, imax, materials[solid.Material.Name], cmin, cmax, null, e.Transform);
                }
            }

            if (e is ITessellate)
            {
                var geo  = (ITessellate)e;
                var mesh = new Elements.Geometry.Mesh();
                geo.Tessellate(ref mesh);

                double[] vertexBuffer;
                double[] normalBuffer;
                ushort[] indexBuffer;
                float[]  colorBuffer;
                double[] vmin; double[] vmax;
                double[] nmin; double[] nmax;
                float[]  cmin; float[] cmax;
                ushort   imin; ushort imax;

                mesh.GetBuffers(out vertexBuffer, out indexBuffer, out normalBuffer, out colorBuffer,
                                out vmax, out vmin, out nmin, out nmax, out cmin,
                                out cmax, out imin, out imax);

                gltf.AddTriangleMesh(e.Id + "_mesh", buffer, vertexBuffer, normalBuffer,
                                     indexBuffer, colorBuffer, vmin, vmax, nmin, nmax,
                                     imin, imax, materials[((IMaterial)e).Material.Name], cmin, cmax, null, e.Transform);
            }

            if (e is IAggregateElement)
            {
                var ae = (IAggregateElement)e;

                if (ae.Elements.Count > 0)
                {
                    foreach (var esub in ae.Elements)
                    {
                        GetRenderDataForElement(esub, gltf, materials, lines, buffer);
                    }
                }
            }
        }
예제 #8
0
        private static void ProcessSolid(Solid solid, Transform t, string id, string materialName, ref Gltf gltf,
                                         ref Dictionary <string, int> materials, ref List <List <Vector3> > lines, ref List <byte> buffer,
                                         List <BufferView> bufferViews, List <Accessor> accessors)
        {
            Elements.Geometry.Mesh mesh = null;
            var currLines = lines.Last();

            foreach (var edge in solid.Edges.Values)
            {
                // Check if we'll overrun the index size
                // for the current line array. If so,
                // create a new line array.
                if (currLines.Count + 2 > ushort.MaxValue)
                {
                    // Console.WriteLine($"Creating new line array at {currLines.Count}.");
                    currLines = new List <Vector3>();
                    lines.Add(currLines);
                }

                if (t != null)
                {
                    currLines.AddRange(new[] { t.OfPoint(edge.Left.Vertex.Point), t.OfPoint(edge.Right.Vertex.Point) });
                }
                else
                {
                    currLines.AddRange(new[] { edge.Left.Vertex.Point, edge.Right.Vertex.Point });
                }
            }

            // var sw = new Stopwatch();
            // sw.Start();

            mesh = new Elements.Geometry.Mesh();
            solid.Tessellate(ref mesh);
            // sw.Stop();
            // Console.WriteLine($"glTF:\t\t{sw.Elapsed} for tessellating the solid.");
            // sw.Reset();

            // sw.Start();
            byte[]   vertexBuffer;
            byte[]   normalBuffer;
            byte[]   indexBuffer;
            byte[]   colorBuffer;
            double[] vmin; double[] vmax;
            double[] nmin; double[] nmax;
            float[]  cmin; float[] cmax;
            ushort   imin; ushort imax;

            mesh.GetBuffers(out vertexBuffer, out indexBuffer, out normalBuffer, out colorBuffer,
                            out vmax, out vmin, out nmin, out nmax, out cmin,
                            out cmax, out imin, out imax);
            // sw.Stop();
            // Console.WriteLine($"glTF:\t\t{sw.Elapsed} for getting the mesh buffers.");
            // sw.Reset();

            // sw.Start();
            gltf.AddTriangleMesh(id + "_mesh", buffer, bufferViews, accessors, vertexBuffer, normalBuffer,
                                 indexBuffer, colorBuffer, vmin, vmax, nmin, nmax,
                                 imin, imax, materials[materialName], cmin, cmax, null, t);
            // sw.Stop();
            // Console.WriteLine($"glTF:\t\t{sw.Elapsed} for adding a triangle mesh.");
            // sw.Reset();
        }
예제 #9
0
        private static void GetRenderDataForElement(IElement e, Gltf gltf,
                                                    Dictionary <string, int> materials, List <List <Vector3> > lines, List <byte> buffer, List <BufferView> bufferViews, List <Accessor> accessors)
        {
            // var sw = new Stopwatch();
            // sw.Start();
            if (e is IAggregateElements)
            {
                var ae = (IAggregateElements)e;

                if (ae.Elements.Count > 0)
                {
                    for (var i = 0; i < ae.Elements.Count; i++)
                    {
                        var esub = ae.Elements[i];
                        GetRenderDataForElement(esub, gltf, materials, lines, buffer, bufferViews, accessors);
                    }
                }
            }
            // sw.Stop();
            // Console.WriteLine($"glTF:\t{sw.Elapsed} for processing aggregates");
            // sw.Reset();

            // sw.Start();
            var materialName = BuiltInMaterials.Default.Name;

            if (e is IElementType <StructuralFramingType> )
            {
                // Get the material from the framing type's material.
                materialName = ((IElementType <StructuralFramingType>)e).ElementType.Material.Name;
            }

            if (e is IElementType <WallType> )
            {
                // Get the material from the first layer of the wall.
                materialName = ((IElementType <WallType>)e).ElementType.MaterialLayers[0].Material.Name;
            }

            if (e is IElementType <FloorType> )
            {
                // Get the material from the first layer of the floor.
                materialName = ((IElementType <FloorType>)e).ElementType.MaterialLayers[0].Material.Name;
            }

            if (e is IMaterial)
            {
                // Get the material from the material property.
                materialName = ((IMaterial)e).Material.Name;
            }
            // sw.Stop();
            // Console.WriteLine($"glTF:\t{sw.Elapsed} for getting the material name.");
            // sw.Reset();

            // sw.Start();
            Solid solid = null;

            if (e is ISolid)
            {
                // Element already has a solid representation.
                var geo = e as ISolid;
                solid = geo.GetUpdatedSolid();
            }
            // sw.Stop();
            // Console.WriteLine($"glTF:\t{sw.Elapsed} for updating element solids.");
            // sw.Reset();

            // sw.Start();
            if (solid != null)
            {
                ProcessSolid(solid, e.Transform, e.Id.ToString(), materialName, ref gltf,
                             ref materials, ref lines, ref buffer, bufferViews, accessors);
            }
            // sw.Stop();
            // Console.WriteLine($"glTF:\t{sw.Elapsed} for processing element solids.");
            // sw.Reset();

            if (e is ITessellate)
            {
                var geo  = (ITessellate)e;
                var mesh = new Elements.Geometry.Mesh();
                geo.Tessellate(ref mesh);

                byte[]   vertexBuffer;
                byte[]   normalBuffer;
                byte[]   indexBuffer;
                byte[]   colorBuffer;
                double[] vmin; double[] vmax;
                double[] nmin; double[] nmax;
                float[]  cmin; float[] cmax;
                ushort   imin; ushort imax;

                mesh.GetBuffers(out vertexBuffer, out indexBuffer, out normalBuffer, out colorBuffer,
                                out vmax, out vmin, out nmin, out nmax, out cmin,
                                out cmax, out imin, out imax);

                gltf.AddTriangleMesh(e.Id + "_mesh", buffer, bufferViews, accessors, vertexBuffer, normalBuffer,
                                     indexBuffer, colorBuffer, vmin, vmax, nmin, nmax,
                                     imin, imax, materials[materialName], cmin, cmax, null, e.Transform);
            }
        }
예제 #10
0
        internal static void ToGlb(this Solid solid, string path)
        {
            var gltf  = new Gltf();
            var asset = new Asset();

            asset.Version   = "2.0";
            asset.Generator = "hypar-gltf";

            gltf.Asset = asset;

            var root = new Node();

            root.Translation = new[] { 0.0f, 0.0f, 0.0f };
            root.Scale       = new[] { 1.0f, 1.0f, 1.0f };

            // Set Z up by rotating -90d around the X Axis
            var q = new Quaternion(new Vector3(1, 0, 0), -Math.PI / 2);

            root.Rotation = new[] {
                (float)q.X, (float)q.Y, (float)q.Z, (float)q.W
            };

            gltf.Nodes = new[] { root };

            gltf.Scene = 0;
            var scene = new Scene();

            scene.Nodes = new[] { 0 };
            gltf.Scenes = new[] { scene };

            gltf.ExtensionsUsed = new[] { "KHR_materials_pbrSpecularGlossiness" };

            var materials = gltf.AddMaterials(new[] { BuiltInMaterials.Default, BuiltInMaterials.Edges, BuiltInMaterials.EdgesHighlighted });

            var buffer = new List <byte>();
            var mesh   = new Elements.Geometry.Mesh();

            solid.Tessellate(ref mesh);

            byte[]   vertexBuffer;
            byte[]   normalBuffer;
            byte[]   indexBuffer;
            byte[]   colorBuffer;
            double[] vmin; double[] vmax;
            double[] nmin; double[] nmax;
            float[]  cmin; float[] cmax;
            ushort   imin; ushort imax;

            mesh.GetBuffers(out vertexBuffer, out indexBuffer, out normalBuffer, out colorBuffer,
                            out vmax, out vmin, out nmin, out nmax, out cmin,
                            out cmax, out imin, out imax);

            var bufferViews = new List <BufferView>();
            var accessors   = new List <Accessor>();

            gltf.AddTriangleMesh("mesh", buffer, bufferViews, accessors, vertexBuffer, normalBuffer,
                                 indexBuffer, colorBuffer, vmin, vmax, nmin, nmax,
                                 imin, imax, materials[BuiltInMaterials.Default.Name], cmin, cmax, null, null);

            var edgeCount           = 0;
            var vertices            = new List <Vector3>();
            var verticesHighlighted = new List <Vector3>();

            foreach (var e in solid.Edges.Values)
            {
                if (e.Left.Loop == null || e.Right.Loop == null)
                {
                    verticesHighlighted.AddRange(new[] { e.Left.Vertex.Point, e.Right.Vertex.Point });
                }
                else
                {
                    vertices.AddRange(new[] { e.Left.Vertex.Point, e.Right.Vertex.Point });
                }

                edgeCount++;
            }

            if (vertices.Count > 0)
            {
                // Draw standard edges
                AddLines(100000, vertices.ToArray(), gltf, materials[BuiltInMaterials.Edges.Name], buffer, bufferViews, accessors);
            }

            if (verticesHighlighted.Count > 0)
            {
                // Draw highlighted edges
                AddLines(100001, verticesHighlighted.ToArray(), gltf, materials[BuiltInMaterials.EdgesHighlighted.Name], buffer, bufferViews, accessors);
            }

            var buff = new glTFLoader.Schema.Buffer();

            buff.ByteLength = buffer.Count;
            gltf.Buffers    = new[] { buff };

            gltf.BufferViews = bufferViews.ToArray();
            gltf.Accessors   = accessors.ToArray();

            if (File.Exists(path))
            {
                File.Delete(path);
            }

            gltf.SaveBinaryModel(buffer.ToArray(), path);
        }
예제 #11
0
        private static void GetRenderDataForElement(Element e,
                                                    Gltf gltf,
                                                    Dictionary <string, int> materials,
                                                    List <byte> buffer,
                                                    List <BufferView> bufferViews,
                                                    List <Accessor> accessors,
                                                    List <glTFLoader.Schema.Mesh> meshes,
                                                    List <glTFLoader.Schema.Node> nodes,
                                                    Dictionary <Guid, List <int> > meshElementMap,
                                                    List <Vector3> lines,
                                                    bool drawEdges)
        {
            var materialName = BuiltInMaterials.Default.Name;
            int meshId       = -1;

            if (e is GeometricElement)
            {
                var geom = (GeometricElement)e;
                materialName = geom.Material.Name;

                geom.UpdateRepresentations();
                if (geom.Representation != null)
                {
                    foreach (var solidOp in geom.Representation.SolidOperations)
                    {
                        if (solidOp.Solid != null)
                        {
                            meshId = ProcessSolid(solidOp.Solid,
                                                  e.Id.ToString(),
                                                  materialName,
                                                  ref gltf,
                                                  ref materials,
                                                  ref buffer,
                                                  bufferViews,
                                                  accessors,
                                                  meshes,
                                                  lines,
                                                  geom.IsElementDefinition ? false : drawEdges,
                                                  geom.Transform);
                            if (!meshElementMap.ContainsKey(e.Id))
                            {
                                meshElementMap.Add(e.Id, new List <int>());
                            }
                            meshElementMap[e.Id].Add(meshId);

                            if (!geom.IsElementDefinition)
                            {
                                CreateNodeForMesh(gltf, meshId, nodes, geom.Transform);
                            }
                        }
                    }
                }
            }

            if (e is ElementInstance)
            {
                var i = (ElementInstance)e;

                // Lookup the corresponding mesh in the map.
                AddInstanceMesh(gltf, nodes, meshElementMap[i.BaseDefinition.Id], i.Transform);

                if (drawEdges)
                {
                    // Get the edges for the solid
                    var geom = i.BaseDefinition;
                    if (geom.Representation != null)
                    {
                        foreach (var solidOp in geom.Representation.SolidOperations)
                        {
                            if (solidOp.Solid != null)
                            {
                                foreach (var edge in solidOp.Solid.Edges.Values)
                                {
                                    lines.AddRange(new[] { i.Transform.OfVector(edge.Left.Vertex.Point), i.Transform.OfVector(edge.Right.Vertex.Point) });
                                }
                            }
                        }
                    }
                }
            }

            if (e is ModelCurve)
            {
                var mc = (ModelCurve)e;
                AddLines(GetNextId(), mc.Curve.RenderVertices(), gltf, materials[mc.Material.Name], buffer, bufferViews, accessors, meshes, nodes, true, mc.Transform);
            }

            if (e is ModelPoints)
            {
                var mp = (ModelPoints)e;
                if (mp.Locations.Count != 0)
                {
                    AddPoints(GetNextId(), mp.Locations, gltf, materials[mp.Material.Name], buffer, bufferViews, accessors, meshes, nodes, mp.Transform);
                }
            }

            if (e is ITessellate)
            {
                var geo  = (ITessellate)e;
                var mesh = new Elements.Geometry.Mesh();
                geo.Tessellate(ref mesh);
                if (mesh == null)
                {
                    return;
                }

                byte[] vertexBuffer;
                byte[] normalBuffer;
                byte[] indexBuffer;
                byte[] colorBuffer;
                byte[] uvBuffer;

                double[] vmin; double[] vmax;
                double[] nmin; double[] nmax;
                float[]  cmin; float[] cmax;
                ushort   imin; ushort imax;
                double[] uvmin; double[] uvmax;

                mesh.GetBuffers(out vertexBuffer,
                                out indexBuffer,
                                out normalBuffer,
                                out colorBuffer,
                                out uvBuffer,
                                out vmax,
                                out vmin,
                                out nmin,
                                out nmax,
                                out cmin,
                                out cmax,
                                out imin,
                                out imax,
                                out uvmax,
                                out uvmin);

                // TODO(Ian): Remove this cast to GeometricElement when we
                // consolidate mesh under geometric representations.
                meshId = gltf.AddTriangleMesh(e.Id + "_mesh",
                                              buffer,
                                              bufferViews,
                                              accessors,
                                              vertexBuffer,
                                              normalBuffer,
                                              indexBuffer,
                                              colorBuffer,
                                              uvBuffer,
                                              vmin,
                                              vmax,
                                              nmin,
                                              nmax,
                                              imin,
                                              imax,
                                              uvmax,
                                              uvmin,
                                              materials[materialName],
                                              cmin,
                                              cmax,
                                              null,
                                              meshes);

                if (!meshElementMap.ContainsKey(e.Id))
                {
                    meshElementMap.Add(e.Id, new List <int>());
                }
                meshElementMap[e.Id].Add(meshId);

                var geom = (GeometricElement)e;
                if (!geom.IsElementDefinition)
                {
                    CreateNodeForMesh(gltf, meshId, nodes, geom.Transform);
                }
            }
        }
예제 #12
0
        /// <summary>
        /// Creates a Roof from a supplied Polygon sketch and a supplied elevation.
        /// </summary>
        /// <param name="model">The input model.</param>
        /// <param name="input">The arguments to the execution.</param>
        /// <returns>A RoofBySketchOutputs instance containing computed results and the model with any new elements.</returns>
        public static RoofBySketchOutputs Execute(Dictionary <string, Model> inputModels, RoofBySketchInputs input)
        {
            var topSide = new Elements.Geometry.Mesh();
            var area    = 0.0;

            foreach (var triangle in input.Mesh.Triangles)
            {
                var a      = topSide.AddVertex(triangle.Vertices[0].Position);
                var b      = topSide.AddVertex(triangle.Vertices[1].Position);
                var c      = topSide.AddVertex(triangle.Vertices[2].Position);
                var triAng =
                    new Elements.Geometry.Triangle(a, b, c);
                topSide.AddTriangle(triAng);
                area += triAng.Area();
            }
            topSide.ComputeNormals();

            // Find the Mesh's lowest point and use the
            // roof thickness to the set the Roof's underside elevation.
            var vertices = input.Mesh.Vertices.ToList();

            vertices = vertices.OrderBy(v => v.Position.Z).ToList();
            var elevation = vertices.First().Position.Z - input.Thickness;

            // Find the topSide Mesh's perimeter points and use them to
            // construct a Mesh representing the underside of the Roof.
            var perimeter = topSide.EdgesPerimeters().First();
            var ePoints   = new List <Vector3>();

            perimeter.ForEach(e => ePoints.AddRange(e.Points()));
            ePoints = ePoints.Distinct().ToList();
            var uPoints = new List <Vector3>();

            ePoints.ForEach(p => uPoints.Add(new Vector3(p.X, p.Y, elevation)));
            var underBoundary = new Polygon(uPoints);
            var underSide     = underBoundary.ToMesh(false);

            // Use the topSide Mesh's edgePoints and the lower Mesh's underPoints
            // to construct a series of triangles forming the sides of the Roof.
            var sideTriangles = new List <Elements.Geometry.Triangle>();

            for (var i = 0; i < ePoints.Count; i++)
            {
                sideTriangles.Add(
                    new Elements.Geometry.Triangle(new Vertex(ePoints[i]),
                                                   new Vertex(uPoints[i]),
                                                   new Vertex(uPoints[(i + 1) % uPoints.Count])));
                sideTriangles.Add(
                    new Elements.Geometry.Triangle(new Vertex(ePoints[i]),
                                                   new Vertex(uPoints[(i + 1) % uPoints.Count]),
                                                   new Vertex(ePoints[(i + 1) % ePoints.Count])));
            }

            // Construct the roof envelope in Elements.Geometry.mesh form.
            // We add vertices individually by position so that we don't affect
            // the original vertices of hte individual faces
            var Envelope = new Elements.Geometry.Mesh();

            foreach (var t in topSide.Triangles)
            {
                var a = Envelope.AddVertex(t.Vertices[0].Position);
                var b = Envelope.AddVertex(t.Vertices[1].Position);
                var c = Envelope.AddVertex(t.Vertices[2].Position);

                Envelope.AddTriangle(new Triangle(a, b, c));
            }
            foreach (var t in underSide.Triangles)
            {
                var a = Envelope.AddVertex(t.Vertices[0].Position);
                var b = Envelope.AddVertex(t.Vertices[1].Position);
                var c = Envelope.AddVertex(t.Vertices[2].Position);

                Envelope.AddTriangle(new Triangle(a, b, c));
            }
            foreach (var t in sideTriangles)
            {
                var a = Envelope.AddVertex(t.Vertices[0].Position);
                var b = Envelope.AddVertex(t.Vertices[1].Position);
                var c = Envelope.AddVertex(t.Vertices[2].Position);

                Envelope.AddTriangle(new Triangle(a, b, c));
            }
            // enVertices.ToList().ForEach(v => Envelope.AddVertex(v));
            // envTriangles.ToList().ForEach(t => Envelope.AddTriangle(t));
            Envelope.ComputeNormals();

            //Record roof high point from topSide mesh.
            var highPoint = topSide.Points().OrderByDescending(p => p.Z).First().Z;

            // // code for when debugging the function.
            // var envelope = MakeEnvelope();
            // var topside = MakeTopside();
            // var underside = MakeUnderside();
            // var underBoundary = Polygon.Rectangle(20.0, 20.0);
            // var elevation = 10.0;
            // var highPoint = 15.0;
            // var area = 100.0;

            var roof =
                new Roof(
                    Envelope,
                    topSide,
                    underSide,
                    underBoundary,
                    elevation,
                    highPoint,
                    input.Thickness,
                    area,
                    new Transform(),
                    BuiltInMaterials.Concrete,
                    null, false, Guid.NewGuid(), "Roof");
            var output = new RoofBySketchOutputs(area);


            output.Model.AddElement(new MeshElement(Envelope, BuiltInMaterials.Concrete));
            output.Model.AddElement(roof);
            return(output);
        }