示例#1
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);
        }