Exemple #1
0
        public Mesh MeshToSpeckle(DB.Mesh mesh, string units = null)
        {
            var vertices = new List <double>(mesh.Vertices.Count * 3);

            foreach (var vert in mesh.Vertices)
            {
                vertices.AddRange(PointToSpeckle(vert).ToList());
            }

            var faces = new List <int>(mesh.NumTriangles * 4);

            for (int i = 0; i < mesh.NumTriangles; i++)
            {
                var triangle = mesh.get_Triangle(i);
                var A        = triangle.get_Index(0);
                var B        = triangle.get_Index(1);
                var C        = triangle.get_Index(2);
                faces.Add(0);
                faces.AddRange(new int[]
                {
                    (int)A, (int)B, (int)C
                });
            }

            var u           = units ?? ModelUnits;
            var speckleMesh = new Mesh(vertices, faces, units: u);

            return(speckleMesh);
        }
Exemple #2
0
        // This is to support raw geometry being sent to Revit (eg from rhino, gh, autocad...)
        public ApplicationPlaceholderObject DirectShapeToNative(Mesh mesh, BuiltInCategory cat = BuiltInCategory.OST_GenericModel)
        {
            // if it comes from GH it doesn't have an applicationId, the use the hash id
            if (mesh.applicationId == null)
            {
                mesh.applicationId = mesh.id;
            }

            var docObj = GetExistingElementByApplicationId(mesh.applicationId);

            //just create new one
            if (docObj != null)
            {
                Doc.Delete(docObj.Id);
            }

            var converted = new List <GeometryObject>();
            var rMesh     = MeshToNative(mesh);

            converted.AddRange(rMesh);

            var catId = Doc.Settings.Categories.get_Item(cat).Id;

            var revitDs = DB.DirectShape.CreateElement(Doc, catId);

            revitDs.ApplicationId     = mesh.applicationId;
            revitDs.ApplicationDataId = Guid.NewGuid().ToString();
            revitDs.SetShape(converted);
            revitDs.Name = "Mesh " + mesh.applicationId;

            return(new ApplicationPlaceholderObject {
                applicationId = mesh.applicationId, ApplicationGeneratedId = revitDs.UniqueId, NativeObject = revitDs
            });
        }
        public Mesh MeshToSpeckle(DB.Mesh mesh, string units = null)
        {
            var speckleMesh = new Mesh();

            foreach (var vert in mesh.Vertices)
            {
                var vertex = PointToSpeckle(vert);
                speckleMesh.vertices.AddRange(new double[] { vertex.x, vertex.y, vertex.z });
            }

            for (int i = 0; i < mesh.NumTriangles; i++)
            {
                var triangle = mesh.get_Triangle(i);
                var A        = triangle.get_Index(0);
                var B        = triangle.get_Index(1);
                var C        = triangle.get_Index(2);
                speckleMesh.faces.Add(0);
                speckleMesh.faces.AddRange(new int[]
                {
                    (int)A, (int)B, (int)C
                });
            }

            speckleMesh.units = units ?? ModelUnits;
            return(speckleMesh);
        }
        public DS.Mesh MeshToNative(Mesh mesh)
        {
            var points = ArrayToPointList(mesh.vertices, mesh.units);
            List <IndexGroup> faces = new List <IndexGroup>();
            int i = 0;

            while (i < mesh.faces.Count)
            {
                if (mesh.faces[i] == 0)
                {
                    // triangle
                    var ig = IndexGroup.ByIndices((uint)mesh.faces[i + 1], (uint)mesh.faces[i + 2], (uint)mesh.faces[i + 3]);
                    faces.Add(ig);
                    i += 4;
                }
                else
                {
                    // quad
                    var ig = IndexGroup.ByIndices((uint)mesh.faces[i + 1], (uint)mesh.faces[i + 2], (uint)mesh.faces[i + 3],
                                                  (uint)mesh.faces[i + 4]);
                    faces.Add(ig);
                    i += 5;
                }
            }

            var dsMesh = DS.Mesh.ByPointsFaceIndices(points, faces);

            dsMesh.SetDynamoProperties <DS.Mesh>(GetDynamicMembersFromBase(mesh));

            return(dsMesh);
        }
        private Mesh SolidToSpeckleMesh(Solid solid)
        {
            var mesh = new Mesh();

            (mesh.faces, mesh.vertices) = GetFaceVertexArrFromSolids(new List <Solid> {
                solid
            });
            mesh.units = ModelUnits;
            return(mesh);
        }
        // Insipred by
        // https://github.com/DynamoDS/DynamoRevit/blob/master/src/Libraries/RevitNodes/GeometryConversion/ProtoToRevitMesh.cs
        public IList <GeometryObject> MeshToNative(Mesh mesh)
        {
            TessellatedShapeBuilderTarget   target   = TessellatedShapeBuilderTarget.Mesh;
            TessellatedShapeBuilderFallback fallback = TessellatedShapeBuilderFallback.Salvage;

            var tsb = new TessellatedShapeBuilder()
            {
                Fallback = fallback, Target = target, GraphicsStyleId = ElementId.InvalidElementId
            };

            tsb.OpenConnectedFaceSet(false);

            var vertices = ArrayToPoints(mesh.vertices, mesh.units);

            int i = 0;

            while (i < mesh.faces.Count)
            {
                var points = new List <XYZ>();

                if (mesh.faces[i] == 0)
                { // triangle
                    points = new List <XYZ> {
                        vertices[mesh.faces[i + 1]], vertices[mesh.faces[i + 2]], vertices[mesh.faces[i + 3]]
                    };
                    var face = new TessellatedFace(points, ElementId.InvalidElementId);
                    tsb.AddFace(face);
                    i += 4;
                }
                else
                { // quad
                    points = new List <XYZ> {
                        vertices[mesh.faces[i + 1]], vertices[mesh.faces[i + 2]], vertices[mesh.faces[i + 4]]
                    };
                    var face1 = new TessellatedFace(points, ElementId.InvalidElementId);
                    tsb.AddFace(face1);
                    points = new List <XYZ> {
                        vertices[mesh.faces[i + 2]], vertices[mesh.faces[i + 3]], vertices[mesh.faces[i + 4]]
                    };
                    var face2 = new TessellatedFace(points, ElementId.InvalidElementId);
                    tsb.AddFace(face2);
                    i += 5;
                }
            }

            tsb.CloseConnectedFaceSet();
            tsb.Build();
            var result = tsb.GetBuildResult();

            return(result.GetGeometricalObjects());
        }
        /// <summary>
        /// Converts a Speckle mesh to a GameObject with a mesh renderer
        /// </summary>
        /// <param name="speckleMesh"></param>
        /// <returns></returns>
        public Mesh MeshToSpeckle(GameObject go)
        {
            //TODO: support multiple filters?
            var filter = go.GetComponent <MeshFilter>();

            if (filter == null)
            {
                return(null);
            }

            //convert triangle array into speckleMesh faces
            List <int> faces = new List <int>();
            int        i     = 0;
            //store them here, makes it like 1000000x faster?
            var triangles = filter.mesh.triangles;

            while (i < triangles.Length)
            {
                faces.Add(0);

                faces.Add(triangles[i + 0]);
                faces.Add(triangles[i + 2]);
                faces.Add(triangles[i + 1]);
                i += 3;
            }

            var mesh = new Mesh();

            // get the speckle data from the go here
            // so that if the go comes from speckle, typed props will get overridden below
            AttachUnityProperties(mesh, go);

            mesh.units = ModelUnits;

            var vertices = filter.mesh.vertices;

            foreach (var vertex in vertices)
            {
                var p  = go.transform.TransformPoint(vertex);
                var sp = PointToSpeckle(p);
                mesh.vertices.Add(sp.x);
                mesh.vertices.Add(sp.y);
                mesh.vertices.Add(sp.z);
            }

            mesh.faces = faces;

            return(mesh);
        }
        // Meshes
        public Mesh MeshToSpeckle(DS.Mesh mesh, string units = null)
        {
            var u             = units ?? ModelUnits;
            var vertices      = PointListToFlatArray(mesh.VertexPositions);
            var defaultColour = System.Drawing.Color.FromArgb(255, 100, 100, 100);

            var faces = mesh.FaceIndices.SelectMany(f =>
            {
                if (f.Count == 4)
                {
                    return(new int[5] {
                        1, (int)f.A, (int)f.B, (int)f.C, (int)f.D
                    });
                }
                else
                {
                    return(new int[4] {
                        0, (int)f.A, (int)f.B, (int)f.C
                    });
                }
            })
                        .ToArray();

            var colors = Enumerable.Repeat(defaultColour.ToArgb(), vertices.Count()).ToArray();
            //double[] textureCoords;

            //if (SpeckleRhinoConverter.AddMeshTextureCoordinates)
            //{
            //  textureCoords = mesh.TextureCoordinates.Select(pt => pt).ToFlatArray();
            //  return new SpeckleMesh(vertices, faces, Colors, textureCoords, properties: mesh.UserDictionary.ToSpeckle());
            //}

            var speckleMesh = new Mesh(vertices, faces, colors, units: u);

            CopyProperties(speckleMesh, mesh);

            using (var box = ComputeMeshBoundingBox(mesh))
                speckleMesh.bbox = BoxToSpeckle(box, u);

            return(speckleMesh);
        }
        public RH.Mesh MeshToNative(Mesh mesh)
        {
            RH.Mesh m = new RH.Mesh();
            m.Vertices.AddVertices(PointListToNative(mesh.vertices, mesh.units));

            int i = 0;

            while (i < mesh.faces.Count)
            {
                if (mesh.faces[i] == 0)
                {
                    // triangle
                    m.Faces.AddFace(new MeshFace(mesh.faces[i + 1], mesh.faces[i + 2], mesh.faces[i + 3]));
                    i += 4;
                }
                else
                {
                    // quad
                    m.Faces.AddFace(new MeshFace(mesh.faces[i + 1], mesh.faces[i + 2], mesh.faces[i + 3], mesh.faces[i + 4]));
                    i += 5;
                }
            }

            try
            {
                m.VertexColors.AppendColors(mesh.colors.Select(c => System.Drawing.Color.FromArgb((int)c)).ToArray());
            }
            catch
            {
            }

            if (mesh.textureCoordinates != null)
            {
                for (int j = 0; j < mesh.textureCoordinates.Count; j += 2)
                {
                    m.TextureCoordinates.Add(mesh.textureCoordinates[j], mesh.textureCoordinates[j + 1]);
                }
            }

            return(m);
        }
        public Mesh MeshToSpeckle(DB.Mesh mesh)
        {
            var speckleMesh = new Mesh();

            foreach (var vert in mesh.Vertices)
            {
                speckleMesh.vertices.AddRange(new double[] { ScaleToSpeckle(vert.X), ScaleToSpeckle(vert.Y), ScaleToSpeckle(vert.Z) });
            }

            for (int i = 0; i < mesh.NumTriangles; i++)
            {
                var triangle = mesh.get_Triangle(i);
                var A        = triangle.get_Index(0);
                var B        = triangle.get_Index(1);
                var C        = triangle.get_Index(2);
                speckleMesh.faces.Add(0);
                speckleMesh.faces.AddRange(new int[] { (int)A, (int)B, (int)C });
            }

            speckleMesh.units = ModelUnits;
            return(speckleMesh);
        }
        // Meshes
        public Mesh MeshToSpeckle(RH.Mesh mesh, string units = null)
        {
            var u     = units ?? ModelUnits;
            var verts = PointsToFlatArray(mesh.Vertices.ToPoint3dArray());

            var Faces = mesh.Faces.SelectMany(face =>
            {
                if (face.IsQuad)
                {
                    return new int[] { 1, face.A, face.B, face.C, face.D }
                }
                ;
                return(new int[] { 0, face.A, face.B, face.C });
            }).ToArray();

            var Colors = mesh.VertexColors.Select(cl => cl.ToArgb()).ToArray();

            var speckleMesh = new Mesh(verts, Faces, Colors, null, u);

            speckleMesh.volume = mesh.Volume();
            speckleMesh.bbox   = BoxToSpeckle(new RH.Box(mesh.GetBoundingBox(true)), u);

            return(speckleMesh);
        }
Exemple #12
0
        // Insipred by
        // https://github.com/DynamoDS/DynamoRevit/blob/master/src/Libraries/RevitNodes/GeometryConversion/ProtoToRevitMesh.cs
        public IList <GeometryObject> MeshToNative(Mesh mesh, TessellatedShapeBuilderTarget target = TessellatedShapeBuilderTarget.Mesh, TessellatedShapeBuilderFallback fallback = TessellatedShapeBuilderFallback.Salvage)
        {
            var tsb = new TessellatedShapeBuilder()
            {
                Fallback = fallback, Target = target, GraphicsStyleId = ElementId.InvalidElementId
            };

            var valid = tsb.AreTargetAndFallbackCompatible(target, fallback);

            tsb.OpenConnectedFaceSet(target == TessellatedShapeBuilderTarget.Solid);

            var vertices = ArrayToPoints(mesh.vertices, mesh.units);

            int i = 0;

            while (i < mesh.faces.Count)
            {
                int n = mesh.faces[i];
                if (n < 3)
                {
                    n += 3; // 0 -> 3, 1 -> 4 to preserve backwards compatibility
                }
                var points = mesh.faces.GetRange(i + 1, n).Select(x => vertices[x]).ToArray();

                if (IsNonPlanarQuad(points))
                {
                    //Non-planar quads will be triangulated as it's more desirable than `TessellatedShapeBuilder.Build`'s attempt to make them planar.
                    //TODO consider triangulating all n > 3 polygons
                    var triPoints = new List <XYZ> {
                        points[0], points[1], points[3]
                    };
                    var face1 = new TessellatedFace(triPoints, ElementId.InvalidElementId);
                    tsb.AddFace(face1);

                    triPoints = new List <XYZ> {
                        points[1], points[2], points[3]
                    };;
                    var face2 = new TessellatedFace(triPoints, ElementId.InvalidElementId);
                    tsb.AddFace(face2);
                }
                else
                {
                    var face = new TessellatedFace(points, ElementId.InvalidElementId);
                    tsb.AddFace(face);
                }

                i += n + 1;
            }

            tsb.CloseConnectedFaceSet();
            try
            {
                tsb.Build();
            }
            catch (Exception e)
            {
                Report.LogConversionError(e);
                return(null);
            }
            var result = tsb.GetBuildResult();

            return(result.GetGeometricalObjects());
        /// <summary>
        /// Converts a Speckle mesh to a GameObject with a mesh renderer
        /// </summary>
        /// <param name="speckleMesh">Mesh to convert</param>
        /// <param name="renderMaterial">If provided will override the renderMaterial on the mesh itself</param>
        /// <param name="properties">If provided will override the properties on the mesh itself</param>
        /// <returns></returns>
        public GameObject MeshToNative(
            Mesh speckleMesh, RenderMaterial renderMaterial = null,
            Dictionary <string, object> properties          = null
            )
        {
            if (speckleMesh.vertices.Count == 0 || speckleMesh.faces.Count == 0)
            {
                return(null);
            }

            var recenterMeshTransforms = true; //TODO: figure out how best to change this?


            var verts = ArrayToPoints(speckleMesh.vertices, speckleMesh.units);


            //convert speckleMesh.faces into triangle array
            List <int> tris = new List <int>();
            int        i    = 0;

            // TODO: Check if this is causing issues with normals for mesh
            while (i < speckleMesh.faces.Count)
            {
                if (speckleMesh.faces[i] == 0)
                {
                    //Triangles
                    tris.Add(speckleMesh.faces[i + 1]);
                    tris.Add(speckleMesh.faces[i + 3]);
                    tris.Add(speckleMesh.faces[i + 2]);
                    i += 4;
                }
                else
                {
                    //Quads to triangles
                    tris.Add(speckleMesh.faces[i + 1]);
                    tris.Add(speckleMesh.faces[i + 3]);
                    tris.Add(speckleMesh.faces[i + 2]);

                    tris.Add(speckleMesh.faces[i + 1]);
                    tris.Add(speckleMesh.faces[i + 4]);
                    tris.Add(speckleMesh.faces[i + 3]);

                    i += 5;
                }
            }


            var go = new GameObject {
                name = speckleMesh.speckle_type
            };
            var mesh = new UnityEngine.Mesh {
                name = speckleMesh.speckle_type
            };

            if (verts.Length >= 65535)
            {
                mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
            }


            // center transform pivot according to the bounds of the model
            if (recenterMeshTransforms)
            {
                Bounds meshBounds = new Bounds
                {
                    center = verts[0]
                };

                foreach (var vert in verts)
                {
                    meshBounds.Encapsulate(vert);
                }

                go.transform.position = meshBounds.center;

                // offset mesh vertices
                for (int l = 0; l < verts.Length; l++)
                {
                    verts[l] -= meshBounds.center;
                }
            }



            mesh.SetVertices(verts);
            mesh.SetTriangles(tris, 0);

            if (speckleMesh.bbox != null)
            {
                var uv = GenerateUV(verts, (float)speckleMesh.bbox.xSize.Length, (float)speckleMesh.bbox.ySize.Length).ToList();
                mesh.SetUVs(0, uv);
            }

            // BUG: causing some funky issues with meshes
            // mesh.RecalculateNormals( );
            mesh.Optimize();
            // Setting mesh to filter once all mesh modifying is done
            go.SafeMeshSet(mesh, true);


            var meshRenderer    = go.AddComponent <MeshRenderer>();
            var speckleMaterial = renderMaterial ?? (RenderMaterial)speckleMesh["renderMaterial"];

            meshRenderer.sharedMaterial = GetMaterial(speckleMaterial);

            //Add mesh collider
            // MeshCollider mc = go.AddComponent<MeshCollider>( );
            // mc.sharedMesh = mesh;
            //mc.convex = true;


            //attach properties on this very mesh
            //means the mesh originated in Rhino or similar
            if (properties == null)
            {
                var meshprops = typeof(Mesh).GetProperties(BindingFlags.Instance | BindingFlags.Public).Select(x => x.Name)
                                .ToList();
                properties = speckleMesh.GetMembers()
                             .Where(x => !meshprops.Contains(x.Key))
                             .ToDictionary(x => x.Key, x => x.Value);
            }

            AttachSpeckleProperties(go, properties);
            return(go);
        }
        public Brep BrepToSpeckle(Solid solid)
        {
#if REVIT2021
            // TODO: Incomplete implementation!!

            var brep = new Brep();
            brep.units = ModelUnits;

            if (solid is null || solid.Faces.IsEmpty)
            {
                return(null);
            }

            var faceIndex    = 0;
            var edgeIndex    = 0;
            var curve2dIndex = 0;
            var curve3dIndex = 0;
            var loopIndex    = 0;
            var trimIndex    = 0;
            var surfaceIndex = 0;

            var speckleFaces       = new Dictionary <Face, BrepFace>();
            var speckleEdges       = new Dictionary <Edge, BrepEdge>();
            var speckleEdgeIndexes = new Dictionary <Edge, int>();
            var speckle3dCurves    = new ICurve[solid.Edges.Size];
            var speckle2dCurves    = new List <ICurve>();
            var speckleLoops       = new List <BrepLoop>();
            var speckleTrims       = new List <BrepTrim>();

            foreach (var face in solid.Faces.Cast <Face>())
            {
                var surface     = FaceToSpeckle(face, out bool orientation, 0.0);
                var iterator    = face.EdgeLoops.ForwardIterator();
                var loopIndices = new List <int>();

                while (iterator.MoveNext())
                {
                    var loop            = iterator.Current as EdgeArray;
                    var loopTrimIndices = new List <int>();
                    // Loop through the edges in the loop.
                    var loopIterator = loop.ForwardIterator();
                    while (loopIterator.MoveNext())
                    {
                        // Each edge should create a 2d curve, a 3d curve, a BrepTrim and a BrepEdge.
                        var edge  = loopIterator.Current as Edge;
                        var faceA = edge.GetFace(0);

                        // Determine what face side are we currently on.
                        var edgeSide = face == faceA ? 0 : 1;

                        // Get curve, create trim and save index
                        var trim       = edge.GetCurveUV(edgeSide);
                        var sTrim      = new BrepTrim(brep, edgeIndex, faceIndex, loopIndex, curve2dIndex, 0, BrepTrimType.Boundary, edge.IsFlippedOnFace(edgeSide), -1, -1);
                        var sTrimIndex = trimIndex;
                        loopTrimIndices.Add(sTrimIndex);

                        // Add curve and trim, increase index counters.
                        speckle2dCurves.Add(CurveToSpeckle(trim.As3DCurveInXYPlane()));
                        speckleTrims.Add(sTrim);
                        curve2dIndex++;
                        trimIndex++;

                        // Check if we have visited this edge before.
                        if (!speckleEdges.ContainsKey(edge))
                        {
                            // First time we visit this edge, add 3d curve and create new BrepEdge.
                            var edgeCurve = edge.AsCurve();
                            speckle3dCurves[curve3dIndex] = CurveToSpeckle(edgeCurve);
                            var sCurveIndex = curve3dIndex;
                            curve3dIndex++;

                            // Create a trim with just one of the trimIndices set, the second one will be set on the opposite condition.
                            var sEdge = new BrepEdge(brep, sCurveIndex, new[] { sTrimIndex }, -1, -1, edge.IsFlippedOnFace(face), null);
                            speckleEdges.Add(edge, sEdge);
                            speckleEdgeIndexes.Add(edge, edgeIndex);
                            edgeIndex++;
                        }
                        else
                        {
                            // Already visited this edge, skip curve 3d
                            var sEdge      = speckleEdges[edge];
                            var sEdgeIndex = speckleEdgeIndexes[edge];
                            sTrim.EdgeIndex = sEdgeIndex;

                            // Update trim indices with new item.
                            // TODO: Make this better.
                            var trimIndices = sEdge.TrimIndices.ToList();
                            trimIndices.Append(sTrimIndex);
                            sEdge.TrimIndices = trimIndices.ToArray();
                        }
                    }

                    var speckleLoop = new BrepLoop(brep, faceIndex, loopTrimIndices, BrepLoopType.Outer);
                    speckleLoops.Add(speckleLoop);
                    var sLoopIndex = loopIndex;
                    loopIndex++;
                    loopIndices.Add(sLoopIndex);
                }

                speckleFaces.Add(face,
                                 new BrepFace(brep, surfaceIndex, loopIndices, loopIndices[0], !face.OrientationMatchesSurfaceOrientation));
                faceIndex++;
                brep.Surfaces.Add(surface);
                surfaceIndex++;
            }

            var mesh = new Mesh();
            (mesh.faces, mesh.vertices) = GetFaceVertexArrFromSolids(new List <Solid> {
                solid
            });
            mesh.units = ModelUnits;
            // TODO: Revit has no brep vertices. Must call 'brep.SetVertices()' in rhino when provenance is revit.
            // TODO: Set tolerances and flags in rhino when provenance is revit.
            brep.Faces        = speckleFaces.Values.ToList();
            brep.Curve2D      = speckle2dCurves;
            brep.Curve3D      = speckle3dCurves.ToList();
            brep.Trims        = speckleTrims;
            brep.Edges        = speckleEdges.Values.ToList();
            brep.Loops        = speckleLoops;
            brep.displayValue = mesh;
            return(brep);
#else
            throw new Exception("Converting BREPs to Speckle is currently only supported in Revit 2021.");
#endif
        }
        // Insipred by
        // https://github.com/DynamoDS/DynamoRevit/blob/master/src/Libraries/RevitNodes/GeometryConversion/ProtoToRevitMesh.cs
        public IList <GeometryObject> MeshToNative(Mesh mesh, TessellatedShapeBuilderTarget target = TessellatedShapeBuilderTarget.Mesh, TessellatedShapeBuilderFallback fallback = TessellatedShapeBuilderFallback.Salvage)
        {
            var tsb = new TessellatedShapeBuilder()
            {
                Fallback = fallback, Target = target, GraphicsStyleId = ElementId.InvalidElementId
            };

            var valid = tsb.AreTargetAndFallbackCompatible(target, fallback);

            tsb.OpenConnectedFaceSet(target == TessellatedShapeBuilderTarget.Solid);

            var vertices = ArrayToPoints(mesh.vertices, mesh.units);

            int i = 0;

            while (i < mesh.faces.Count)
            {
                var points = new List <XYZ>();

                if (mesh.faces[i] == 0)
                { // triangle
                    points = new List <XYZ> {
                        vertices[mesh.faces[i + 1]], vertices[mesh.faces[i + 2]], vertices[mesh.faces[i + 3]]
                    };
                    var face  = new TessellatedFace(points, ElementId.InvalidElementId);
                    var check = !tsb.DoesFaceHaveEnoughLoopsAndVertices(face);
                    tsb.AddFace(face);
                    i += 4;
                }
                else
                { // quad
                    points = new List <XYZ> {
                        vertices[mesh.faces[i + 1]], vertices[mesh.faces[i + 2]], vertices[mesh.faces[i + 4]]
                    };
                    var face1  = new TessellatedFace(points, ElementId.InvalidElementId);
                    var check1 = tsb.DoesFaceHaveEnoughLoopsAndVertices(face1);
                    tsb.AddFace(face1);
                    points = new List <XYZ> {
                        vertices[mesh.faces[i + 2]], vertices[mesh.faces[i + 3]], vertices[mesh.faces[i + 4]]
                    };
                    var face2  = new TessellatedFace(points, ElementId.InvalidElementId);
                    var check2 = tsb.DoesFaceHaveEnoughLoopsAndVertices(face2);

                    tsb.AddFace(face2);
                    i += 5;
                }
            }

            tsb.CloseConnectedFaceSet();
            try
            {
                tsb.Build();
            }
            catch (Exception e)
            {
                ConversionErrors.Add(e);
                return(null);
            }
            var result = tsb.GetBuildResult();

            return(result.GetGeometricalObjects());
        }