private XbimTriangulatedMesh Triangulate(IIfcTriangulatedFaceSet triangulation) { var faceId = 0; var entityLabel = triangulation.EntityLabel; var precision = (float)triangulation.Model.ModelFactors.Precision; var faceCount = triangulation.CoordIndex.Count(); var triangulatedMesh = new XbimTriangulatedMesh(faceCount, precision); //add all the vertices in to the mesh var vertices = new List <int>(triangulation.Coordinates.CoordList.Count()); foreach (var coord in triangulation.Coordinates.CoordList) { var tpl = coord.AsTriplet <IfcLengthMeasure>(); var v = new Vec3(tpl.A, tpl.B, tpl.C); var idx = triangulatedMesh.AddVertex(v); vertices.Add(idx); } foreach (var triangleFace in triangulation.CoordIndex) { var tpl = triangleFace.AsTriplet <IfcPositiveInteger>(); triangulatedMesh.AddTriangle(vertices[(int)tpl.A - 1], vertices[(int)tpl.B - 1], vertices[(int)tpl.C - 1], faceId); } triangulatedMesh.UnifyFaceOrientation(entityLabel); return(triangulatedMesh); }
private XbimTriangulatedMesh TriangulateFaces(IList <IIfcFace> ifcFaces, int entityLabel, float precision) { var faceId = 0; var faceCount = ifcFaces.Count; var triangulatedMesh = new XbimTriangulatedMesh(faceCount, precision); foreach (var ifcFace in ifcFaces) { //improves performance and reduces memory load var tess = new Tess(); var contours = new List <ContourVertex[]>(/*Count?*/); foreach (var bound in ifcFace.Bounds) //build all the loops { var polyLoop = bound.Bound as IIfcPolyLoop; if (polyLoop == null) { continue; //skip empty faces } var polygon = polyLoop.Polygon; if (polygon.Count < 3) { continue; //skip non-polygonal faces } var is3D = (polygon[0].Dim == 3); var contour = new ContourVertex[polygon.Count]; if (bound.Orientation) { for (var j = 0; j < polygon.Count; j++) { var v = new Vec3(polygon[j].X, polygon[j].Y, is3D ? polygon[j].Z : 0); triangulatedMesh.AddVertex(v, ref contour[j]); } } else { var i = 0; for (var j = polygon.Count - 1; j >= 0; j--) { var v = new Vec3(polygon[j].X, polygon[j].Y, is3D ? polygon[j].Z : 0); triangulatedMesh.AddVertex(v, ref contour[i]); i++; } } contours.Add(contour); } if (contours.Any()) { if (contours.Count == 1 && contours[0].Length == 3) //its a triangle just grab it { triangulatedMesh.AddTriangle(contours[0][0].Data, contours[0][1].Data, contours[0][2].Data, faceId); faceId++; } //else //if (contours.Count == 1 && contours[0].Length == 4) //its a quad just grab it //{ // foreach (var v in contours[0]) // { // Console.WriteLine("{0:F4} ,{1:F4}, {2:F4}", v.Position.X, v.Position.Y, v.Position.Z); // } // Console.WriteLine(""); // triangulatedMesh.AddTriangle(contours[0][0].Data, contours[0][1].Data, contours[0][3].Data, faceId); // triangulatedMesh.AddTriangle(contours[0][3].Data, contours[0][1].Data, contours[0][2].Data, faceId); // faceId++; //} else //it is multi-sided and may have holes { tess.AddContours(contours); tess.Tessellate(WindingRule.EvenOdd, ElementType.Polygons, 3); var faceIndices = new List <int>(tess.ElementCount * 3); var elements = tess.Elements; var contourVerts = tess.Vertices; for (var j = 0; j < tess.ElementCount * 3; j++) { var idx = contourVerts[elements[j]].Data; if (idx < 0) //WE HAVE INSERTED A POINT { //add it to the mesh triangulatedMesh.AddVertex(contourVerts[elements[j]].Position, ref contourVerts[elements[j]]); } faceIndices.Add(contourVerts[elements[j]].Data); } if (faceIndices.Count > 0) { for (var j = 0; j < tess.ElementCount; j++) { var p1 = faceIndices[j * 3]; var p2 = faceIndices[j * 3 + 1]; var p3 = faceIndices[j * 3 + 2]; triangulatedMesh.AddTriangle(p1, p2, p3, faceId); } faceId++; } } } } triangulatedMesh.UnifyFaceOrientation(entityLabel); return(triangulatedMesh); }