private IXbimShapeGeometryData MeshPolyhedronText(IEnumerable<IEnumerable<IfcFace>> facesList, int entityLabel,float precision) { IXbimShapeGeometryData shapeGeometry = new XbimShapeGeometry(); shapeGeometry.Format = (byte)XbimGeometryType.Polyhedron; using (var ms = new MemoryStream(0x4000)) using (TextWriter textWriter = new StreamWriter(ms)) { var faceLists = facesList as IList<IEnumerable<IfcFace>> ?? facesList.ToList(); var triangulations = new List<XbimTriangulatedMesh>(faceLists.Count); foreach (var faceList in faceLists) triangulations.Add(TriangulateFaces(faceList, entityLabel, precision)); // Write out header uint verticesCount = 0; uint triangleCount = 0; uint facesCount = 0; var boundingBox = XbimRect3D.Empty; foreach (var triangulatedMesh in triangulations) { verticesCount += triangulatedMesh.VertexCount; triangleCount += triangulatedMesh.TriangleCount; facesCount += (uint)triangulatedMesh.Faces.Count; if (boundingBox.IsEmpty) boundingBox = triangulatedMesh.BoundingBox; else boundingBox.Union(triangulatedMesh.BoundingBox); } textWriter.WriteLine("P {0} {1} {2} {3} {4}", 2, verticesCount, facesCount, triangleCount, 0); //write out vertices and normals textWriter.Write("V"); foreach (var p in triangulations.SelectMany(t => t.Vertices)) textWriter.Write(" {0},{1},{2}", p.X, p.Y, p.Z); textWriter.WriteLine(); //now write out the faces uint verticesOffset = 0; foreach (var triangulatedMesh in triangulations) { foreach (var faceGroup in triangulatedMesh.Faces) { textWriter.Write("T"); int currentNormal = -1; foreach (var triangle in faceGroup.Value) { var pn1 = triangle[0].PackedNormal.ToUnit16(); var pn2 = triangle[0].NextEdge.PackedNormal.ToUnit16(); var pn3 = triangle[0].NextEdge.NextEdge.PackedNormal.ToUnit16(); if (pn1 != currentNormal) { textWriter.Write(" {0}/{1},", triangle[0].StartVertexIndex + verticesOffset, pn1); currentNormal = pn1; } else textWriter.Write(" {0},", triangle[0].StartVertexIndex + verticesOffset); if (pn1 != pn2) { textWriter.Write("{0}/{1},", triangle[0].NextEdge.StartVertexIndex + verticesOffset, pn2); currentNormal = pn2; } else textWriter.Write("{0},", triangle[0].NextEdge.StartVertexIndex + verticesOffset); if (pn2 != pn3) { textWriter.Write("{0}/{1}", triangle[0].NextEdge.NextEdge.StartVertexIndex + verticesOffset, pn3); currentNormal = pn3; } else textWriter.Write("{0}", triangle[0].NextEdge.NextEdge.StartVertexIndex + verticesOffset); } textWriter.WriteLine(); } verticesOffset += triangulatedMesh.VertexCount; } textWriter.Flush(); shapeGeometry.BoundingBox = boundingBox.ToFloatArray(); shapeGeometry.ShapeData = ms.ToArray(); } return shapeGeometry; }
private void WriteShapeGeometry(JsonWriter writer, XbimShapeGeometry geom, XbimMatrix3D? transform = null) { XbimMeshGeometry3D mesh = new XbimMeshGeometry3D(); mesh.Read(geom.ShapeData, transform); writer.WritePropertyName("positions"); writer.WriteStartArray(); foreach (var point in mesh.Positions) { writer.WriteValue(Math.Round(point.X,4)); //we are converting to metres so this is effectively .1mm writer.WriteValue(Math.Round(point.Y,4)); writer.WriteValue(Math.Round(point.Z,4)); } writer.WriteEndArray(); writer.WritePropertyName("indices"); writer.WriteStartArray(); foreach (var idx in mesh.TriangleIndices) { writer.WriteValue(idx); } writer.WriteEndArray(); writer.WritePropertyName("normals"); writer.WriteStartArray(); foreach (var norm in mesh.Normals) { writer.WriteValue(norm.X); writer.WriteValue(norm.Y); writer.WriteValue(norm.Z); } writer.WriteEndArray(); }
private IXbimShapeGeometryData MeshPolyhedronBinary(IEnumerable<IEnumerable<IfcFace>> facesList, int entityLabel, float precision) { IXbimShapeGeometryData shapeGeometry = new XbimShapeGeometry(); shapeGeometry.Format = (byte)XbimGeometryType.PolyhedronBinary; using (var ms = new MemoryStream(0x4000)) using (var binaryWriter = new BinaryWriter(ms)) { var faceLists = facesList as IList<IEnumerable<IfcFace>> ?? facesList.ToList(); var triangulations = new List<XbimTriangulatedMesh>(faceLists.Count); foreach (var faceList in faceLists) triangulations.Add(TriangulateFaces(faceList, entityLabel, precision)); // Write out header uint verticesCount = 0; uint triangleCount = 0; uint facesCount = 0; var boundingBox = XbimRect3D.Empty; foreach (var triangulatedMesh in triangulations) { verticesCount += triangulatedMesh.VertexCount; triangleCount += triangulatedMesh.TriangleCount; facesCount += (uint)triangulatedMesh.Faces.Count; if (boundingBox.IsEmpty) boundingBox = triangulatedMesh.BoundingBox; else boundingBox.Union(triangulatedMesh.BoundingBox); } binaryWriter.Write((byte)1); //stream format version // ReSharper disable once RedundantCast binaryWriter.Write((UInt32)verticesCount); //number of vertices binaryWriter.Write(triangleCount); //number of triangles foreach (var v in triangulations.SelectMany(t=>t.Vertices)) { binaryWriter.Write(v.X); binaryWriter.Write(v.Y); binaryWriter.Write(v.Z); } shapeGeometry.BoundingBox = boundingBox.ToFloatArray(); //now write out the faces binaryWriter.Write(facesCount); uint verticesOffset = 0; int invalidNormal = ushort.MaxValue; ; foreach (var triangulatedMesh in triangulations) { foreach (var faceGroup in triangulatedMesh.Faces) { var numTrianglesInFace = faceGroup.Value.Count; //we need to fix this var planar = invalidNormal != faceGroup.Key; //we have a mesh of faces that all have the same normals at their vertices if (!planar) numTrianglesInFace *= -1; //set flag to say multiple normals binaryWriter.Write((Int32)numTrianglesInFace); bool first = true; foreach (var triangle in faceGroup.Value) { if (planar && first) { triangle[0].PackedNormal.Write(binaryWriter); first = false; } WriteIndex(binaryWriter, (uint)triangle[0].StartVertexIndex + verticesOffset, verticesCount); if (!planar) triangle[0].PackedNormal.Write(binaryWriter); WriteIndex(binaryWriter, (uint)triangle[0].NextEdge.StartVertexIndex + verticesOffset, verticesCount); if (!planar) triangle[0].NextEdge.PackedNormal.Write(binaryWriter); WriteIndex(binaryWriter, (uint)triangle[0].NextEdge.NextEdge.StartVertexIndex + verticesOffset, verticesCount); if (!planar) triangle[0].NextEdge.NextEdge.PackedNormal.Write(binaryWriter); } } verticesOffset += triangulatedMesh.VertexCount; } binaryWriter.Flush(); shapeGeometry.ShapeData = ms.ToArray(); } return shapeGeometry; }