/***************************************************/ /**** Public Methods ****/ /***************************************************/ public static List <Mesh> Meshes(this XbimShapeInstance instance, Xbim3DModelContext context) { if (instance == null) { BH.Engine.Reflection.Compute.RecordError("The meshes could not be extracted because the IFC element is null."); return(null); } if (context == null) { BH.Engine.Reflection.Compute.RecordError("The meshes could not be extracted because the 3D model context is null."); return(null); } List <Mesh> result; //Instance's geometry XbimShapeGeometry geometry = context.ShapeGeometry(instance); byte[] data = ((IXbimShapeGeometryData)geometry).ShapeData; //If you want to get all the faces and trinagulation use this using (var stream = new MemoryStream(data)) { using (var reader = new BinaryReader(stream)) { XbimShapeTriangulation shape = reader.ReadShapeTriangulation(); result = shape.Meshes(); } } TransformMatrix transform = instance.Transformation.TransformMatrixFromIfc(); return(result.Select(x => x.Transform(transform)).ToList()); }
private static XbimShapeTriangulation GetMeshes(Xbim3DModelContext context, IIfcProduct product) { XbimShapeTriangulation ifcMesh = null;; var productShape = context.ShapeInstancesOf(product) .Where(p => p.RepresentationType != XbimGeometryRepresentationType.OpeningsAndAdditionsExcluded) .Distinct(); if (productShape.Any()) { var shapeInstance = productShape.FirstOrDefault(); var shapeGeometry = context.ShapeGeometry(shapeInstance.ShapeGeometryLabel); byte[] data = ((IXbimShapeGeometryData)shapeGeometry).ShapeData; //If you want to get all the faces and triangulation use this using (var stream = new MemoryStream(data)) { using (var reader = new BinaryReader(stream)) { ifcMesh = reader.ReadShapeTriangulation(); } } } return(ifcMesh); }
/***************************************************/ public static List <Mesh> Meshes(this XbimShapeTriangulation shape) { if (shape == null) { BH.Engine.Reflection.Compute.RecordError("The meshes could not be extracted because the shape triangulation model is null."); return(null); } List <Mesh> result = new List <Mesh>(); List <Point> allVertices = shape.Vertices.Select(x => x.PointFromIfc()).ToList(); foreach (XbimFaceTriangulation subMesh in shape.Faces) { Mesh mesh = new Mesh(); List <int> uniqueIds = subMesh.Indices.Distinct().ToList(); mesh.Vertices = uniqueIds.Select(i => allVertices[i]).ToList(); for (int i = 0; i < subMesh.TriangleCount; i++) { mesh.Faces.Add(new Face { A = uniqueIds.IndexOf(subMesh.Indices[3 * i]), B = uniqueIds.IndexOf(subMesh.Indices[3 * i + 1]), C = uniqueIds.IndexOf(subMesh.Indices[3 * i + 2]) }); } result.Add(mesh); } return(result); }
private static void getgeometry(XbimShapeInstance shape, Xbim3DModelContext m_context, int entityLabel, int number_of_shapes) { XbimShapeTriangulation mesh = null; var geometry = m_context.ShapeGeometry(shape); Console.WriteLine($"{"\n"}{GetIndent(11)}{"--Geometry Type: " + geometry.Format}"); var ms = new MemoryStream(((IXbimShapeGeometryData)geometry).ShapeData); var br = new BinaryReader(ms); mesh = br.ReadShapeTriangulation(); mesh = mesh.Transform(((XbimShapeInstance)shape).Transformation); var facesfound = mesh.Faces.ToList(); var number_of_faces = facesfound.Count(); Console.WriteLine($"{"\n"}{GetIndent(11)}{" -----No. of faces on the shape #" + shape.IfcProductLabel + ": " + number_of_faces}"); //used for an ID for each face int face_index = 0; //used for the total number of triangles int number_of_triangles = 0; //write the Faces element with its count xmlWriter.WriteStartElement("Faces"); xmlWriter.WriteAttributeString("NumFaces", number_of_faces.ToString()); foreach (XbimFaceTriangulation f in facesfound) { number_of_triangles = f.TriangleCount; Console.WriteLine($"{"\n"}{GetIndent(13)}{" -----Triangle count on face: " + f.GetType() + " :mesh is " + number_of_triangles}"); face_index++; composetrianglesets(f, mesh, entityLabel, facesfound.Count(), face_index, number_of_triangles, number_of_shapes); } //this ends the faces element in the xml file xmlWriter.WriteEndElement(); //Console.WriteLine($"{"\n"}{GetIndent(13)}{" -----Vertices of the shape: #" + shape.IfcProductLabel}"); //foreach (var v in mesh.Vertices.ToList()) //{ // Console.WriteLine($"{GetIndent(13)}{" --vertex_" + mesh.Vertices.ToList().IndexOf(v) + " : " + Math.Round((double)v.X, 2) + " | " + Math.Round((double)v.Y, 2) + " | " + Math.Round((double)v.Z, 2)}"); //} Console.WriteLine("\n"); }
private static void getgeometry(XbimShapeInstance shape, Xbim3DModelContext m_context, int entityLabel, int number_OF_Walls) { XbimShapeTriangulation mesh = null; var geometry = m_context.ShapeGeometry(shape); //Console.WriteLine("====" + geometry.GetType()); Console.WriteLine($"{"\n"}{GetIndent(11)}{"--Geometry Type: " + geometry.Format}"); var ms = new MemoryStream(((IXbimShapeGeometryData)geometry).ShapeData); var br = new BinaryReader(ms); mesh = br.ReadShapeTriangulation(); mesh = mesh.Transform(((XbimShapeInstance)shape).Transformation); var facesfound = mesh.Faces.ToList(); Console.WriteLine($"{"\n"}{GetIndent(11)}{" -----No. of faces on the shape #" + shape.IfcProductLabel + ": " + facesfound.Count()}"); int FaceNum = 0; int Triangle_Count = 0; //xmlWriter.WriteElementString("Faces", facesfound.Count().ToString()); xmlWriter.WriteStartElement("Faces"); xmlWriter.WriteAttributeString("NumFaces", facesfound.Count().ToString()); foreach (XbimFaceTriangulation f in facesfound) { Triangle_Count = f.TriangleCount; Console.WriteLine($"{"\n"}{GetIndent(13)}{" -----Triangle count on face: " + f.GetType() + " :mesh is " +Triangle_Count}"); //foreach (var fi in f.Indices) //{ // Console.WriteLine($"{GetIndent(13)}{" -> " + fi}"); //} FaceNum++; composetrianglesets(f, mesh, entityLabel, facesfound.Count(), FaceNum, Triangle_Count, number_OF_Walls); } //this is for the faces NUmber xmlWriter.WriteEndElement(); // xmlWriter.WriteWhitespace("\n"); //Console.WriteLine($"{"\n"}{GetIndent(13)}{" -----Vertices of the shape: #" + shape.IfcProductLabel}"); //foreach (var v in mesh.Vertices.ToList()) //{ // Console.WriteLine($"{GetIndent(13)}{" --vertex_" + mesh.Vertices.ToList().IndexOf(v) + " : " + Math.Round((double)v.X, 2) + " | " + Math.Round((double)v.Y, 2) + " | " + Math.Round((double)v.Z, 2)}"); //} Console.WriteLine("\n"); }
public static MeshGeometry3D WriteTriangles(IIfcProduct ifcElement, Xbim3DModelContext context, XbimMatrix3D wcsTransformation) { MeshBuilder meshBuilder = new MeshBuilder(false, false); // var allTriangles = new List<Triangles>(); // foreach (XbimShapeInstance instance in context.ShapeInstancesOf(ifcElement).Where(x => x.RepresentationType == XbimGeometryRepresentationType.OpeningsAndAdditionsIncluded)) foreach (XbimShapeInstance instance in context.ShapeInstancesOf(ifcElement).Where(x => x.RepresentationType == XbimGeometryRepresentationType.OpeningsAndAdditionsIncluded)) { XbimShapeGeometry geometry = context.ShapeGeometry(instance); var data = ((IXbimShapeGeometryData)geometry).ShapeData; using (var stream = new MemoryStream(data)) { using (var reader = new BinaryReader(stream)) { XbimShapeTriangulation mesh = reader.ReadShapeTriangulation(); mesh = mesh.Transform(instance.Transformation); // WCS transforms mesh = mesh.Transform(wcsTransformation); foreach (XbimFaceTriangulation face in mesh.Faces) { var j = 0; for (var i = 0; i < face.TriangleCount; i++) { int k = i + j; var point1 = new Point3D { X = mesh.Vertices[face.Indices[k]].X, Y = mesh.Vertices[face.Indices[k]].Y, Z = mesh.Vertices[face.Indices[k]].Z }; j++; k = i + j; var point2 = new Point3D { X = mesh.Vertices[face.Indices[k]].X, Y = mesh.Vertices[face.Indices[k]].Y, Z = mesh.Vertices[face.Indices[k]].Z }; j++; k = i + j; var point3 = new Point3D { X = mesh.Vertices[face.Indices[k]].X, Y = mesh.Vertices[face.Indices[k]].Y, Z = mesh.Vertices[face.Indices[k]].Z }; meshBuilder.AddTriangle(point1, point2, point3); } } } } } return(meshBuilder.ToMesh()); // return allTriangles; }
public void IfcTriangulatedFaceSetComplexBinaryTest() { using (var store = IfcStore.Open("IFC4TessellationComplex.ifc")) { var triangulatedFaceSet = store.Instances[4373] as IIfcTriangulatedFaceSet; var tessellator = new XbimTessellator(store, XbimGeometryType.PolyhedronBinary); Assert.IsNotNull(triangulatedFaceSet); Assert.IsTrue(tessellator.CanMesh(triangulatedFaceSet)); var geom = tessellator.Mesh(triangulatedFaceSet); using (var ms = new MemoryStream(((IXbimShapeGeometryData)geom).ShapeData)) { using (var br = new BinaryReader(ms)) { XbimShapeTriangulation myShapeTriangulation = br.ReadShapeTriangulation(); Assert.IsTrue(myShapeTriangulation.Faces.Sum(t => t.TriangleCount) == triangulatedFaceSet.NumberOfTriangles); } } } }
private static void getgeometry(XbimShapeInstance shape, Xbim3DModelContext m_context) { XbimShapeTriangulation mesh = null; var geometry = m_context.ShapeGeometry(shape); //Console.WriteLine("====" + geometry.GetType()); Console.WriteLine($"{"\n"}{GetIndent(11)}{"--Geometry Type: " + geometry.Format}"); var ms = new MemoryStream(((IXbimShapeGeometryData)geometry).ShapeData); var br = new BinaryReader(ms); mesh = br.ReadShapeTriangulation(); mesh = mesh.Transform(((XbimShapeInstance)shape).Transformation); var facesfound = mesh.Faces.ToList(); Console.WriteLine($"{"\n"}{GetIndent(11)}{" -----No. of faces on the shape #" + shape.IfcProductLabel + ": " + facesfound.Count()}"); foreach (XbimFaceTriangulation f in facesfound) { Console.WriteLine($"{"\n"}{GetIndent(13)}{" -----Triangle count on face: " + f.GetType() + " :mesh is " + f.TriangleCount}"); //foreach (var fi in f.Indices) //{ // Console.WriteLine($"{GetIndent(13)}{" -> " + fi}"); //} composetrianglesets(f, mesh); } //Console.WriteLine($"{"\n"}{GetIndent(13)}{" -----Vertices of the shape: #" + shape.IfcProductLabel}"); //foreach (var v in mesh.Vertices.ToList()) //{ // Console.WriteLine($"{GetIndent(13)}{" --vertex_" + mesh.Vertices.ToList().IndexOf(v) + " : " + Math.Round((double)v.X, 2) + " | " + Math.Round((double)v.Y, 2) + " | " + Math.Round((double)v.Z, 2)}"); //} Console.WriteLine("\n"); }
public BimTriangulation(XbimShapeTriangulation triangulation, float scale, Vector3 offset, XbimMatrix3D matrix = new XbimMatrix3D(), bool bMatrix = false) { if (bMatrix) { bimTriangulation = triangulation.Transform(matrix); } else { bimTriangulation = triangulation; } vertices = new List <Vector3>(); normals = new List <Vector3>(); bimTriangulation.ToPointsWithNormalsAndIndices(out List <float[]> points, out List <int> indices); triangles = indices; foreach (var p in points) { //原版减去了一个offset,但是我发现不计算offset所有偏移都是正确的 //var vertice = new Vector3(p[0], p[1], p[2]) / scale - offset; var vertice = new Vector3(p[0], p[1], p[2]) / scale; var normal = new Vector3(p[3], p[4], p[5]); vertices.Add(vertice); normals.Add(normal); } /* * foreach (var v in bimTriangulation.Vertices) * vertices.Add(new Vector3((float)v.X, (float)v.Y, (float)v.Z) / scale - offset); * foreach(var f in bimTriangulation.Faces) * { * triangles.AddRange(f.Indices); * foreach(var n in f.Normals) * { * normals.Add(new Vector3((float)n.Normal.X, (float)n.Normal.Y, (float)n.Normal.Z)); * } * } */ }
public MyBimTriangulation(XbimShapeTriangulation triangulation, Vector3 offsite, float scale, XbimMatrix3D matrix = default, bool bMatrix = false) { if (bMatrix) { bimTriangulation = triangulation.Transform(matrix); } else { bimTriangulation = triangulation; } vertices = new List <Vector3>(); normals = new List <Vector3>(); bimTriangulation.ToPointsWithNormalsAndIndices(out List <float[]> points, out List <int> indices); triangles = indices; foreach (var p in points) { var vertice = new Vector3(p[0], p[1], p[2]) / scale - offsite; var normal = new Vector3(p[3], p[4], p[5]); vertices.Add(vertice); normals.Add(normal); } //foreach (var v in bimTriangulation.Vertices) //{ // vertices.Add(new Vector3((float)v.X, (float)v.Y, (float)v.Z) / scale - offsite); //} //foreach (var f in bimTriangulation.Faces) //{ // triangles.AddRange(f.Indices); // foreach (var n in f.Normals) // { // var nor = new Vector3((float)n.Normal.X, (float)n.Normal.Y, (float)n.Normal.Z); // normals.Add(nor); // } //} }
private static void composetrianglesets(XbimFaceTriangulation face, XbimShapeTriangulation shapemesh) { Dictionary <string, List <int> > triangles = new Dictionary <string, List <int> >(); Dictionary <string, XbimPoint3D> vertices = new Dictionary <string, XbimPoint3D>(); List <XbimPoint3D> verts = shapemesh.Vertices.ToList(); //for (int i = 0; i < verts.Count(); i++) //{ // string name = "vertex_" + (i).ToString(); // vertices.Add(name, verts[i]); //} //foreach (var v in vertices) //{ // Console.WriteLine($"{GetIndent(15)}{v.Key + ": "}{v.Value.X + ", "}{v.Value.Y + ", "}{v.Value.Z}"); //} /*******************************************************************************************************/ for (int i = 0; i < face.TriangleCount; i++) { string name = "triangle_" + (i + 1).ToString(); triangles.Add(name, face.Indices.ToList().GetRange(i * 3, 3)); } foreach (var x in triangles) { var vert1 = x.Value[0]; var vert2 = x.Value[1]; var vert3 = x.Value[2]; Console.WriteLine($"{"\n"}{GetIndent(15)}{x.Key + ": "}{vert1 + ","}{vert2 + ","}{vert3}"); Console.WriteLine($"{GetIndent(15)}{"---------------------"}"); for (int y = 0; y < x.Value.Count(); y++) { Console.WriteLine($"{GetIndent(15)}{"vertex_"+ x.Value[y] + ": "}{Math.Round((double)verts[x.Value[y]].X, 2)}{"|"}{Math.Round((double)verts[x.Value[y]].Y, 2)}{"|"}{Math.Round((double)verts[x.Value[y]].Z, 2)}"); } } /*******************************************************************************************************/ }
public BimTriangulation(XbimShapeTriangulation shapeTriangulation, Vector3 offsite, float scale, XbimMatrix3D xbimMatrix = default, bool shapeRepetite = false) { if (shapeRepetite) { this.shapeTriangulation = shapeTriangulation.Transform(xbimMatrix); } else { this.shapeTriangulation = shapeTriangulation; } vertices = new List <Vector3>(); normals = new List <Vector3>(); this.shapeTriangulation.ToPointsWithNormalsAndIndices(out List <float[]> points, out List <int> indices); triangles = indices; foreach (var p in points) { Vector3 vertice = new Vector3(p[0], p[1], p[2]) / scale - offsite; Vector3 normal = new Vector3(p[3], p[4], p[5]); vertices.Add(vertice); normals.Add(normal); } }
/// <summary> /// read geomotry data from wexbim file /// </summary> /// <param name="fileName"></param> public static void ReadWexbimFile(string fileName) { Vector3 offsite; using (var fs = new FileStream(fileName, FileMode.Open, FileAccess.Read)) { using (var br = new BinaryReader(fs)) { var magicalNum = br.ReadInt32(); var version = br.ReadByte(); var shapeCount = br.ReadInt32(); var vertexCount = br.ReadInt32(); var triangleCount = br.ReadInt32(); var matrixCount = br.ReadInt32(); var productCount = br.ReadInt32(); var styleCount = br.ReadInt32(); var scale = br.ReadSingle(); var regionCount = br.ReadInt16(); //Region for (int i = 0; i < regionCount; i++) { var population = br.ReadInt32(); var centreX = br.ReadSingle(); centreX /= scale; var centreY = br.ReadSingle(); centreY /= scale; var centreZ = br.ReadSingle(); centreZ /= scale; var boundsBytes = br.ReadBytes(6 * sizeof(float)); var bounds = XbimRect3D.FromArray(boundsBytes); bounds.X /= scale; bounds.Y /= scale; bounds.Z /= scale; bounds.SizeX /= scale; bounds.SizeY /= scale; bounds.SizeZ /= scale; MyBimGeomorty.regions.Add(new MyBimRegion(population, centreX, centreY, centreZ, (float)bounds.SizeX, (float)bounds.SizeY, (float)bounds.SizeZ)); } offsite = MyBimGeomorty.regions[0].position; //texture for (int i = 0; i < styleCount; i++) { var styleId = br.ReadInt32(); var red = br.ReadSingle(); var green = br.ReadSingle(); var blue = br.ReadSingle(); var alpha = br.ReadSingle(); MyBimGeomorty.colors.Add(new MyBimColor(styleId, red, green, blue, alpha)); } //product for (int i = 0; i < productCount; i++) { var entityLabel = br.ReadInt32(); var typeId = br.ReadInt16(); var boxBytes = br.ReadBytes(6 * sizeof(float)); XbimRect3D bb = XbimRect3D.FromArray(boxBytes); //float x = (float)bb.X, y = (float)bb.Y, z = (float)bb.Z; //float sizeX = (float)bb.SizeX, sizeY = (float)bb.SizeY, sizeZ = (float)bb.SizeZ; MyBimGeomorty.products.Add(new MyBimProduct(entityLabel, typeId)); } //shape for (int i = 0; i < shapeCount; i++) { var shapeRepetition = br.ReadInt32(); MyBimShapeInstance si; if (shapeRepetition > 1) { List <MyBimShapeInstance> curShapeInstances = new List <MyBimShapeInstance>(); for (int j = 0; j < shapeRepetition; j++) { var ifcProductLabel = br.ReadInt32(); var ifcTypeId = br.ReadInt16(); var instanceLabel = br.ReadInt32(); var styleLabel = br.ReadInt32(); var transform = XbimMatrix3D.FromArray(br.ReadBytes(sizeof(double) * 16)); si = new MyBimShapeInstance(ifcProductLabel, ifcTypeId, instanceLabel, styleLabel, transform); //MyBimGeomorty.shapeInstances.Add(si); curShapeInstances.Add(si); var p = MyBimGeomorty.products.Find(product => product.entityLabel == ifcProductLabel); p.AddShapeInstance(si); } var triangulation = br.ReadShapeTriangulation(); foreach (var csi in curShapeInstances) { var tri = new MyBimTriangulation(triangulation, offsite, scale, csi.transform, true); csi.AddTriangulation(tri); //MyBimGeomorty.triangulations.Add(tri); } } else if (shapeRepetition == 1) { var ifcProductLabel = br.ReadInt32(); var ifcTypeId = br.ReadInt16(); var instanceLabel = br.ReadInt32(); var styleLabel = br.ReadInt32(); si = new MyBimShapeInstance(ifcProductLabel, ifcTypeId, instanceLabel, styleLabel); //MyBimGeomorty.shapeInstances.Add(si); var p = MyBimGeomorty.products.Find(product => product.entityLabel == ifcProductLabel); p.AddShapeInstance(si); XbimShapeTriangulation triangulation = br.ReadShapeTriangulation(); var tri = new MyBimTriangulation(triangulation, offsite, scale); //MyBimGeomorty.triangulations.Add(tri); si.AddTriangulation(tri); } } } } }
public static List <Point3D> GetFootPrintNonBREP(IIfcProduct ifcElement, Xbim3DModelContext context) { var resultList = new List <Point3D>(); foreach (XbimShapeInstance instance in context.ShapeInstancesOf(ifcElement)) { // Get the IFC Representation of the Footprint of the instance XbimShapeGeometry geometry = context.ShapeGeometry(instance); var data = ((IXbimShapeGeometryData)geometry).ShapeData; using (var stream = new MemoryStream(data)) { using (var reader = new BinaryReader(stream)) { XbimShapeTriangulation mesh = reader.ReadShapeTriangulation(); mesh = mesh.Transform(instance.Transformation); // find the minimal z coordinate double minZ = 10000; foreach (var vertex in mesh.Vertices) { if (vertex.Z <= minZ) { minZ = vertex.Z; } } List <IVertex> points = new List <IVertex>(); foreach (var vertex in mesh.Vertices) { if (vertex.Z != minZ) { continue; } points.Add(new DefaultVertex { Position = new[] { vertex.X, vertex.Y } }); } if (points.Count <= 2) { return(null); } // Compute ConvexHull var cH = ConvexHull.Create(points); foreach (var item in cH.Points) { var point = new Point3D() { X = item.Position[0], Y = item.Position[1], Z = minZ }; bool duplicate = false; foreach (var result in resultList) { if (result == point) { duplicate = true; break; } } if (!duplicate) { resultList.Add(point); } } } } } return(resultList); }
private void GetModel(XbimShapeTriangulation shapeTriangulation, int styleId, int ifcProductLabel) { //生成模型 GameObject go = Instantiate(prefab); Mesh mesh = new Mesh(); go.GetComponent <MeshFilter>().mesh = mesh; List <XbimPoint3D> xbimPoint3Ds = new List <XbimPoint3D>(); xbimPoint3Ds = (List <XbimPoint3D>)shapeTriangulation.Vertices; List <Vector3> vector3s = new List <Vector3>(); List <int> indices = new List <int>(); List <Vector2> uvs = new List <Vector2>(); List <float[]> positions = new List <float[]>(); List <Vector3> vertices = new List <Vector3>(); List <Vector3> normals = new List <Vector3>(); foreach (var points in xbimPoint3Ds) { vector3s.Add(new Vector3((float)points.X, (float)points.Y, (float)points.Z)); } foreach (var face in (List <XbimFaceTriangulation>)shapeTriangulation.Faces) { foreach (var indice in face.Indices) { indices.Add(indice); } foreach (var uv in face.Normals) { //normals.Add(new Vector3((float)uv.Normal.X, (float)uv.Normal.Y, (float)uv.Normal.Z)); uvs.Add(new Vector2(uv.U, uv.V)); } } shapeTriangulation.ToPointsWithNormalsAndIndices(out positions, out indices); foreach (var position in positions) { vertices.Add(new Vector3(position[0] / scale, position[1] / scale, position[2] / scale)); normals.Add(new Vector3(position[3], position[4], position[5])); } mesh.vertices = vertices.ToArray(); //mesh.vertices = vector3s.ToArray(); //mesh.uv = uvs.ToArray(); mesh.triangles = indices.ToArray(); //mesh.Optimize(); //mesh.RecalculateNormals(); mesh.normals = normals.ToArray(); //赋予材质 Material material = new Material(Shader.Find("CrossSection/OnePlaneBSP")); Vector4 color = new Vector4(); styleDictionary.TryGetValue(styleId, out color); material.color = color; go.GetComponent <Renderer>().material = material; //设置父子关系 GameObject parent; productDictionary.TryGetValue(ifcProductLabel, out parent); go.transform.SetParent(parent.transform); go.AddComponent <PlaneCuttingController>(); }
public static void ReadWexBim(string wexBimPath) { //Dictionary<int, BimColor> colors = new Dictionary<int, BimColor>(); List <BimColor> colors = new List <BimColor>(); List <BimRegion> regions = new List <BimRegion>(); List <BimProduct> products = new List <BimProduct>(); using (var fs = new FileStream(wexBimPath, FileMode.Open, FileAccess.Read)) { float scale = 0f;//关系到模型实际大小的比例 Vector3 offset = Vector3.zero; using (var br = new BinaryReader(fs)) { var magicNumber = br.ReadInt32(); var version = br.ReadByte(); var shapeCount = br.ReadInt32(); var vertexCount = br.ReadInt32(); var triangleCount = br.ReadInt32(); var matrixCount = br.ReadInt32(); var productCount = br.ReadInt32(); var styleCount = br.ReadInt32(); var meter = br.ReadSingle(); var regionCount = br.ReadInt16(); scale = meter; for (int i = 0; i < regionCount; i++) { var population = br.ReadInt32(); var centreX = br.ReadSingle(); var centreY = br.ReadSingle(); var centreZ = br.ReadSingle(); var boundsBytes = br.ReadBytes(6 * sizeof(float)); var modelBounds = XbimRect3D.FromArray(boundsBytes); BimRegion region = new BimRegion(population, centreX, centreY, centreZ, (float)modelBounds.SizeX, (float)modelBounds.SizeY, (float)modelBounds.SizeZ); regions.Add(region); } offset = regions[0].position; for (int i = 0; i < styleCount; i++) { var styleId = br.ReadInt32(); var red = br.ReadSingle(); var green = br.ReadSingle(); var blue = br.ReadSingle(); var alpha = br.ReadSingle(); BimColor color = new BimColor(styleId, red, green, blue, alpha); colors.Add(color); } for (int i = 0; i < productCount; i++) { var productLabel = br.ReadInt32(); var productType = br.ReadInt16(); var boxBytes = br.ReadBytes(6 * sizeof(float)); BimProduct product = new BimProduct(productLabel, productType); /* * XbimRect3D bb = XbimRect3D.FromArray(boxBytes); * XbimPoint3D doubleCenter = XbimPoint3D.Add(bb.Min, bb.Max); * BimProduct product = new BimProduct(productLabel, productType, (float)doubleCenter.X / 2, (float)doubleCenter.Y / 2, * (float)doubleCenter.Z / 2, (float)bb.SizeX, (float)bb.SizeY, (float)bb.SizeZ); */ products.Add(product); } for (int i = 0; i < shapeCount; i++) { var shapeRepetition = br.ReadInt32(); if (shapeRepetition > 1) { List <BimShape> thisShape = new List <BimShape>(); for (int j = 0; j < shapeRepetition; j++) { var ifcProductLabel = br.ReadInt32(); var instanceTypeId = br.ReadInt16(); var instanceLabel = br.ReadInt32(); var styleId = br.ReadInt32(); var transform = XbimMatrix3D.FromArray(br.ReadBytes(sizeof(double) * 16)); BimShape shape = new BimShape(ifcProductLabel, instanceTypeId, instanceLabel, styleId, transform); thisShape.Add(shape); var p = products.Find(product => product.entityLabel == ifcProductLabel); p.shapes.Add(shape); } var triangulation = br.ReadShapeTriangulation(); foreach (var s in thisShape) { var tri = new BimTriangulation(triangulation, scale, offset, s.transform, true); s.triangulations.Add(tri); } } else if (shapeRepetition == 1) { var ifcProductLabel = br.ReadInt32(); var instanceTypeId = br.ReadInt16(); var instanceLabel = br.ReadInt32(); var styleId = br.ReadInt32(); XbimShapeTriangulation triangulation = br.ReadShapeTriangulation(); BimShape shape = new BimShape(ifcProductLabel, instanceTypeId, instanceLabel, styleId); var p = products.Find(product => product.entityLabel == ifcProductLabel); p.shapes.Add(shape); var tri = new BimTriangulation(triangulation, scale, offset); shape.triangulations.Add(tri); } } } } ModelCreater.CreateModel(products, colors); }
/// <summary> /// Runs tessselation with Xbim scene context /// </summary> /// <param name="model">The model to be exported</param> /// <param name="summary">The scene export summary</param> /// <param name="monitor">The progress emitter instance</param> /// <returns>An enumerable of tesselated product representations</returns> public IEnumerable <IfcProductSceneRepresentation> Tesselate(IModel model, IfcSceneExportSummary summary, CancelableProgressing monitor) { ReadGeometryStore(model, monitor); short[] excludeTypeId = ExcludeExpressType.Select(t => model.Metadata.ExpressTypeId(t.ExpressName)).ToArray(); Array.Sort(excludeTypeId); // Start reading the geometry store built before using (var gReader = model.GeometryStore.BeginRead()) { int totalCount = gReader.ShapeGeometries.Count(); int currentCount = 0; // Product label vs. Component and candidate shape labels var packageCache = new SortedDictionary <int, TesselationPackage>(); // Compute contexts ComputeContextTransforms(gReader, summary, ContextsCreateFromSettings(gReader, summary)); monitor?.NotifyProgressEstimateUpdate(totalCount); foreach (var geometry in gReader.ShapeGeometries) { if (monitor?.State.IsAboutCancelling ?? false) { monitor.State.MarkCanceled(); break; } currentCount++; monitor?.State.UpdateDone(currentCount, "Running tesselation..."); monitor?.NotifyOnProgressChange(); if (geometry.ShapeData.Length <= 0) { // No geometry continue; } var shapes = gReader.ShapeInstancesOfGeometry(geometry.ShapeLabel) .Where(i => 0 > Array.BinarySearch(excludeTypeId, i.IfcTypeId) && i.RepresentationType == XbimGeometryRepresentationType.OpeningsAndAdditionsIncluded); if (!shapes.Any()) { // No shape instances continue; } using (var ms = new MemoryStream(((IXbimShapeGeometryData)geometry).ShapeData)) { using (var br = new BinaryReader(ms)) { XbimShapeTriangulation tr = br.ReadShapeTriangulation(); foreach (XbimShapeInstance shape in shapes) { if (monitor?.State.IsAboutCancelling ?? false) { monitor.State.MarkCanceled(); break; } var product = model.Instances[shape.IfcProductLabel] as IIfcProduct; // Try first to find the referenced component TesselationPackage pkg; if (!packageCache.TryGetValue(shape.IfcProductLabel, out pkg)) { // New component ToDo shape tuple built from component and todo ShapeGeometryLabel pkg = new TesselationPackage(gReader.ShapeInstancesOfEntity(product)); packageCache[shape.IfcProductLabel] = pkg; } var ctx = summary.ContextOf(shape.RepresentationContext); if (null == ctx) { Logger?.LogWarning($"Shape of representation #{shape.RepresentationContext} of product #{product.EntityLabel} out of context scope. Skipped."); continue; } // Check for representation var representation = GetOrCreateRepresentation(summary, shape, pkg); if (!pkg.IsShapeGeometryDone(geometry)) { AppendVertices(representation, summary, tr.Vertices); } // TODO Use "bias" definition to adjust biased local offsets var body = new FaceBody { Material = new RefId { Nid = shape.StyleLabel > 0 ? shape.StyleLabel : shape.IfcTypeId * -1 }, Transform = CreateTransform(summary, shape), PtSet = (uint)representation.Points.Count - 1, }; foreach (var face in tr.Faces) { if (face.Indices.Count % 3 != 0) { throw new NotSupportedException("Expecting triangular meshes only"); } // Translate Xbim face definition var bodyFace = new Face { IsPlanar = face.IsPlanar, Mesh = new Mesh { Type = FacetType.TriMesh, Orient = Orientation.Ccw } }; switch (face.NormalCount) { case 0: // No normals at all break; case 1: // Single normal bodyFace.IsPlanar = true; face.Normals[0].Normal.AppendTo(bodyFace.Mesh.Normal); break; default: // No planar face if (face.NormalCount != face.Indices.Count) { throw new NotSupportedException($"Incorrect count of normals per face mesh (expecting {face.Indices.Count}, have {face.NormalCount}"); } foreach (var n in face.Normals.Select(n => n.Normal)) { n.AppendTo(bodyFace.Mesh.Normal); } break; } bodyFace.Mesh.Vertex.AddRange(face.Indices.Select(i => (uint)i)); body.Faces.Add(bodyFace); } // Add body to known component representation.Bodies.Add(body); // Remove geometry label from todo list pkg.RemoveDone(shape); // If no shape instances left if (pkg.IsDone) { yield return(pkg.ToSceneRepresentation(shape.IfcProductLabel)); packageCache.Remove(shape.IfcProductLabel); } } } } } // Return most recent if (packageCache.Count > 0) { Logger?.LogWarning($"Detected {packageCache.Count} unfinished geometry entries. Missing shapes."); foreach (var e in packageCache) { // Announce missing components even if unfinished due to some reason Logger?.LogWarning($"IfcProduct #{e.Key} misses {e.Value.CountOpenInstances} shape(s)."); yield return(e.Value.ToSceneRepresentation(e.Key)); } } } monitor?.NotifyOnProgressChange("Done tesselation."); }
private static void composetrianglesets(XbimFaceTriangulation face, XbimShapeTriangulation shapemesh, int entityLabel, int Number_Faces, int faceNum, int triangle_Count, int number_OF_Walls) { Dictionary <string, List <int> > triangles = new Dictionary <string, List <int> >(); Dictionary <string, XbimPoint3D> vertices = new Dictionary <string, XbimPoint3D>(); List <XbimPoint3D> verts = shapemesh.Vertices.ToList(); xmlWriter.WriteStartElement("Face"); xmlWriter.WriteAttributeString("ID", faceNum.ToString()); //for (int i = 0; i < verts.Count(); i++) //{ // string name = "vertex_" + (i).ToString(); // vertices.Add(name, verts[i]); //} //foreach (var v in vertices) //{ // Console.WriteLine($"{GetIndent(15)}{v.Key + ": "}{v.Value.X + ", "}{v.Value.Y + ", "}{v.Value.Z}"); //} /*******************************************************************************************************/ xmlWriter.WriteStartElement("Triangles"); xmlWriter.WriteAttributeString("Triangle_Number", triangle_Count.ToString()); for (int i = 0; i < face.TriangleCount; i++) { string name = "triangle_" + (i + 1).ToString(); triangles.Add(name, face.Indices.ToList().GetRange(i * 3, 3)); } int IDtriangle = 0; foreach (var x in triangles) { xmlWriter.WriteStartElement("Triangle"); xmlWriter.WriteAttributeString("ID", IDtriangle.ToString()); var vert1 = x.Value[0]; var vert2 = x.Value[1]; var vert3 = x.Value[2]; Console.WriteLine($"{"\n"}{GetIndent(15)}{x.Key + ": "}{vert1 + ","}{vert2 + ","}{vert3}"); Console.WriteLine($"{GetIndent(15)}{"---------------------"}"); xmlWriter.WriteStartElement("Vertices"); xmlWriter.WriteAttributeString("VerticeNum", "3"); for (int y = 0; y < x.Value.Count(); y++) { var VerticeID = "vertex_" + x.Value[y]; Console.WriteLine($"{GetIndent(15)}{VerticeID+": "}{Math.Round((double)verts[x.Value[y]].X, 2)}{"|"}{Math.Round((double)verts[x.Value[y]].Y, 2)}{"|"}{Math.Round((double)verts[x.Value[y]].Z, 2)}"); xmlWriter.WriteStartElement("Vertice"); xmlWriter.WriteAttributeString("ID", VerticeID); xmlWriter.WriteElementString("X", (Math.Round((double)verts[x.Value[y]].X, 2).ToString)()); //xmlWriter.WriteString((Math.Round((double)verts[x.Value[y]].X, 2).ToString)()); // xmlWriter.WriteEndElement(); // xmlWriter.WriteWhitespace("\n"); xmlWriter.WriteElementString("Y", (Math.Round((double)verts[x.Value[y]].Y, 2).ToString)()); // xmlWriter.WriteEndElement(); // xmlWriter.WriteWhitespace("\n"); xmlWriter.WriteElementString("Z", (Math.Round((double)verts[x.Value[y]].Z, 2).ToString)()); // xmlWriter.WriteString(( // xmlWriter.WriteEndElement(); // xmlWriter.WriteWhitespace("\n"); // Console.WriteLine("Wall_ID: " + entityLabel + " Face_Number :" + faceNum + " triangle_Count :" + triangle_Count + " triangle_index :" + x.Key + " Number_Vertices :" + x.Value.Count + $"{GetIndent(15)}{"vertex_" + x.Value[y] + ": "}{Math.Round((double)verts[x.Value[y]].X, 2)}{"|"}{Math.Round((double)verts[x.Value[y]].Y, 2)}{"|"}{Math.Round((double)verts[x.Value[y]].Z, 2)}"); //XmlWriter writer = XmlWriter.Create("C:\\Users\\aniru\\Desktop\\wall.xml"); //this is for the verticeID // xmlWriter.WriteEndElement(); // xmlWriter.WriteWhitespace("\n"); xmlWriter.WriteEndElement(); } //this is for the vertices xmlWriter.WriteEndElement(); // xmlWriter.WriteWhitespace("\n"); //this is for the triangle id xmlWriter.WriteEndElement(); // xmlWriter.WriteWhitespace("\n"); IDtriangle++; } //this is for the triangle Number xmlWriter.WriteEndElement(); // xmlWriter.WriteWhitespace("\n"); //this is for the face id xmlWriter.WriteEndElement(); // xmlWriter.WriteWhitespace("\n"); // XElement Walls = //new XElement("Walls", new XAttribute("NumWalls", number_OF_Walls), // new XElement("WallId", entityLabel.ToString(), // new XElement("Faces", new XAttribute("NumFaces", Number_Faces), // new XElement("FaceIndex", faceNum, // new XElement("Triangles", new XAttribute("NumTriangles", triangle_Count), // new XElement("TriangleIndex", x.Key, // new XElement("Vertices", new XAttribute("NumVertices", x.Value.Count), // new XElement("VerticeIndex", "vertex_" + x.Value[y], // new XElement("X", 2, // new XElement("Y", 3, // new XElement("Z", 4))))))))))); ////Console.WriteLine("_____________00000000______"+Walls.Element("WallId").ToString()); //Walls.Descendants("Faces").FirstOrDefault(el => el.Attribute("NumFaces") != null).Add("xii", 3); //Console.WriteLine("------------------------------------"+Walls.Element("WallId").ToString()); //Console.WriteLine("------------------------------------!" + Walls.Element("VerticeIndex")); //Console.WriteLine("------------------------------------!" + Walls.Descendants("Vertices")); // foreach (var ad in Walls.Descendants("VerticeIndex")) //{ // ad.Add(new XElement("xii", 2)); // Console.WriteLine("sdasdasdasd"); //} //// Walls.Element("VerticeIndex").Add("ass", 2); // Console.WriteLine(result.ToString()); // Walls.Element("Faces")..Add(new XElement("xaaa", 2)); //for (int j=0; j< x.Value.Count();j++) //{ // Walls.Element("VerticeIndex").Add(new XElement("x", Math.Round((double)verts[x.Value[y]].X, 2)), // new XElement("Y", Math.Round((double)verts[x.Value[y]].Y, 2)), // new XElement("Z", Math.Round((double)verts[x.Value[y]].Z, 2))); //} //String filename = "Walls.xml"; //var doc = new XDocument(); //if (File.Exists(filename)) //{ //// Console.WriteLine("======================================================the file existsssssss "); // //doc = XDocument.Load(filename); // //doc.Element("Walls").Add(Walls); // XDocument xdoc = XDocument.Load("Walls.xml"); // xdoc.Element("Walls").Add(Walls); //append after the last backup element // xdoc.Save("Walls.xml"); //} //else //{ // // Console.WriteLine("___________________________________________________the file doesntttttttttttttt 000000 existsssssss "); // Walls.Save("Walls.xml"); //} //Console.WriteLine(str); // XElement root = new XElement("Walls",new XAttribute("NumWalls",number_OF_Walls), //new XElement("WallID", "child content"), //new XElement("DASD","sdasda", // new XElement("asdweq","asdwqwe")) // root.Save("root.xml"); ////Console.WriteLine(str11); /*******************************************************************************************************/ }
void Start() { //Mesh mesh = new Mesh(); //List<> string path = @"E:\Unity\BIMForUnity\Assets\test1.wexbim"; using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read)) { using (var br = new BinaryReader(fs)) { var magicNumber = br.ReadInt32(); var version = br.ReadByte(); var shapeCount = br.ReadInt32(); var vertexCount = br.ReadInt32(); var triangleCount = br.ReadInt32(); var matrixCount = br.ReadInt32(); var productCount = br.ReadInt32(); var styleCount = br.ReadInt32(); var meter = br.ReadSingle(); scale = meter; var regionCount = br.ReadInt16(); for (int i = 0; i < regionCount; i++) { var population = br.ReadInt32(); var centreX = br.ReadSingle(); var centreY = br.ReadSingle(); var centreZ = br.ReadSingle(); var boundsBytes = br.ReadBytes(6 * sizeof(float)); var modelBounds = XbimRect3D.FromArray(boundsBytes); } for (int i = 0; i < styleCount; i++) { var styleId = br.ReadInt32(); var red = br.ReadSingle(); var green = br.ReadSingle(); var blue = br.ReadSingle(); var alpha = br.ReadSingle(); styleDictionary.Add(styleId, new Vector4(red, green, blue, alpha)); } for (int i = 0; i < productCount; i++) { var productLabel = br.ReadInt32(); var productType = br.ReadInt16(); var boxBytes = br.ReadBytes(6 * sizeof(float)); XbimRect3D bb = XbimRect3D.FromArray(boxBytes); GameObject go = new GameObject(productLabel.ToString()); go.transform.SetParent(GameObject.Find("Model").transform); //储存productLabel productDictionary.Add(productLabel, go); } for (int i = 0; i < shapeCount; i++) { var shapeRepetition = br.ReadInt32(); // Assert.IsTrue(shapeRepetition > 0); if (shapeRepetition > 1) { Material material = new Material(Shader.Find("CrossSection/OnePlaneBSP")); Vector4 color = new Vector4(); List <int> ifcProductLabels = new List <int>(); List <int> styleIds = new List <int>(); List <XbimMatrix3D> transforms = new List <XbimMatrix3D>(); for (int j = 0; j < shapeRepetition; j++) { var ifcProductLabel = br.ReadInt32(); var instanceTypeId = br.ReadInt16(); var instanceLabel = br.ReadInt32(); var styleId = br.ReadInt32(); var transform = XbimMatrix3D.FromArray(br.ReadBytes(sizeof(double) * 16)); styleDictionary.TryGetValue(styleId, out color); ifcProductLabels.Add(ifcProductLabel); styleIds.Add(styleId); transforms.Add(transform); //Debug.Log(transform.ToString()); } var triangulation = br.ReadShapeTriangulation(); //// Assert.IsTrue(triangulation.Vertices.Count > 0, "Number of vertices should be greater than zero"); for (int j = 0; j < shapeRepetition; j++) { GetModel(triangulation.Transform(transforms[j]), styleIds[j], ifcProductLabels[j]); } } else if (shapeRepetition == 1) { var ifcProductLabel = br.ReadInt32(); var instanceTypeId = br.ReadInt16(); var instanceLabel = br.ReadInt32(); var styleId = br.ReadInt32(); XbimShapeTriangulation triangulation = br.ReadShapeTriangulation(); // Assert.IsTrue(triangulation.Vertices.Count > 0, "Number of vertices should be greater than zero"); //--------------------------------------------- //GetModel(triangulation, styleId, ifcProductLabel); } } } GameObject.Find("Model").transform.eulerAngles = new Vector3(-90, 0, 0); } }
public static List <Polygon> ConvertMesh3DTo2DPolygons(XbimShapeTriangulation vMesh3D, bool isClosed) { if (vMesh3D == null) { return(new List <Polygon>()); } var finalPolygons = new List <Polygon>(); var vPoint2DCol = new List <Point2D>(); var positions = new List <float[]>(); var indices = new List <int>(); vMesh3D.ToPointsWithNormalsAndIndices(out positions, out indices); var sameSurfaceIndices = new Dictionary <double, List <int> >(); for (var x = 0; x <= indices.Count - 1; x += 3) { var pos1 = positions[indices[x]]; var pos2 = positions[indices[x + 1]]; var pos3 = positions[indices[x + 2]]; if (pos1[2] == pos2[2] && pos2[2] == pos3[2]) { if (!sameSurfaceIndices.ContainsKey(pos1[2])) { sameSurfaceIndices.Add(pos1[2], new List <int>()); } sameSurfaceIndices[pos1[2]].Add(indices[x]); sameSurfaceIndices[pos1[2]].Add(indices[x + 1]); sameSurfaceIndices[pos1[2]].Add(indices[x + 2]); } } for (var x = 0; x <= positions.Count - 1; x++) { vPoint2DCol.Add(new Point2D(positions[x][0], positions[x][1])); } var vNewIndices = new List <int>(); var vNewPos = new List <Point2D>(); int vIndex1; int vIndex2; int vIndex3; Triangle vTriangle; List <Triangle> vListTriangles = new List <Triangle>(); Point2D p1, p2, p3; foreach (var sameSurface in sameSurfaceIndices) { var shapePolygon = new Polygon(); for (var x = 0; x <= sameSurface.Value.Count - 1; x += 3) { p1 = vPoint2DCol[sameSurface.Value[x]]; p2 = vPoint2DCol[sameSurface.Value[x + 1]]; p3 = vPoint2DCol[sameSurface.Value[x + 2]]; vTriangle = new Triangle(p1, p2, p3); if (!vTriangle.IsValid) { continue; } vIndex1 = vNewPos.IndexOf(p1); vIndex2 = vNewPos.IndexOf(p2); vIndex3 = vNewPos.IndexOf(p3); if (!vListTriangles.Contains(vTriangle)) { vListTriangles.Add(vTriangle); if (vIndex1 != -1) { vNewIndices.Add(vIndex1); } else { vNewIndices.Add(vNewPos.Count); vNewPos.Add(p1); } if (vIndex2 != -1) { vNewIndices.Add(vIndex2); } else { vNewIndices.Add(vNewPos.Count); vNewPos.Add(p2); } if (vIndex3 != -1) { vNewIndices.Add(vIndex3); } else { vNewIndices.Add(vNewPos.Count); vNewPos.Add(p3); } } } /// lets try this feature var boundaryPath = EdgeHelpers.GetEdges(vNewIndices.ToArray()).FindBoundary().SortEdges(); foreach (var pathStep in boundaryPath) { shapePolygon.PolygonVertices.Add(vNewPos[pathStep.v1]); } finalPolygons.Add(shapePolygon); } return(finalPolygons); }
public const int WexBimId = 94132117; // Magic /// <summary> /// This function is used to generate the .wexbim model files. /// </summary> /// <param name="model">The model to export</param> /// <param name="binaryStream">An open writable streamer.</param> /// <param name="products">Optional products to be written to the wexBIM file. If null, all products from the model will be saved</param> /// <param name="translation">Optional 3D vector to apply</param> public static void SaveAsWexBim(this IModel model, BinaryWriter binaryStream, IEnumerable <IIfcProduct> products = null, IVector3D translation = null) { products = products ?? model.Instances.OfType <IIfcProduct>(); // ReSharper disable RedundantCast if (model.GeometryStore == null) { throw new XbimException("Geometry store has not been initialised"); } // ReSharper disable once CollectionNeverUpdated.Local var colourMap = new XbimColourMap(); using (var geomRead = model.GeometryStore.BeginRead()) { var lookup = geomRead.ShapeGeometries; var styles = geomRead.StyleIds; var regions = geomRead.ContextRegions.SelectMany(r => r).ToList(); //we need to get all the default styles for various products var defaultStyles = geomRead.ShapeInstances.Select(i => - (int)i.IfcTypeId).Distinct(); var allStyles = defaultStyles.Concat(styles).ToList(); int numberOfGeometries = 0; int numberOfVertices = 0; int numberOfTriangles = 0; int numberOfMatrices = 0; int numberOfProducts = 0; int numberOfStyles = allStyles.Count; //start writing out binaryStream.Write((Int32)WexBimId); //magic number binaryStream.Write((byte)2); //version of stream, arrays now packed as doubles var start = (int)binaryStream.Seek(0, SeekOrigin.Current); binaryStream.Write((Int32)0); //number of shapes binaryStream.Write((Int32)0); //number of vertices binaryStream.Write((Int32)0); //number of triangles binaryStream.Write((Int32)0); //number of matrices binaryStream.Write((Int32)0); //number of products binaryStream.Write((Int32)numberOfStyles); //number of styles binaryStream.Write(Convert.ToSingle(model.ModelFactors.OneMetre)); //write out conversion to meter factor binaryStream.Write(Convert.ToInt16(regions.Count)); //write out the population data var t = XbimMatrix3D.Identity; t = Translate(t, translation); foreach (var r in regions) { binaryStream.Write((Int32)(r.Population)); var bounds = r.ToXbimRect3D(); var centre = t.Transform(r.Centre); //write out the centre of the region binaryStream.Write((Single)centre.X); binaryStream.Write((Single)centre.Y); binaryStream.Write((Single)centre.Z); //bounding box of largest region binaryStream.Write(bounds.ToFloatArray()); } //textures foreach (var styleId in allStyles) { XbimColour colour; if (styleId > 0) { var ss = (IIfcSurfaceStyle)model.Instances[styleId]; var texture = XbimTexture.Create(ss); colour = texture.ColourMap.FirstOrDefault(); } else //use the default in the colour map for the enetity type { var theType = model.Metadata.GetType((short)Math.Abs(styleId)); colour = colourMap[theType.Name]; } if (colour == null) { colour = XbimColour.DefaultColour; } binaryStream.Write((Int32)styleId); //style ID binaryStream.Write((Single)colour.Red); binaryStream.Write((Single)colour.Green); binaryStream.Write((Single)colour.Blue); binaryStream.Write((Single)colour.Alpha); } //write out all the product bounding boxes var prodIds = new HashSet <int>(); foreach (var product in products) { if (product is IIfcFeatureElement) { continue; } prodIds.Add(product.EntityLabel); var bb = XbimRect3D.Empty; foreach (var si in geomRead.ShapeInstancesOfEntity(product)) { var transformation = Translate(si.Transformation, translation); var bbPart = XbimRect3D.TransformBy(si.BoundingBox, transformation); //make sure we put the box in the right place and then convert to axis aligned if (bb.IsEmpty) { bb = bbPart; } else { bb.Union(bbPart); } } //do not write out anything with no geometry if (bb.IsEmpty) { continue; } binaryStream.Write((Int32)product.EntityLabel); binaryStream.Write((UInt16)model.Metadata.ExpressTypeId(product)); binaryStream.Write(bb.ToFloatArray()); numberOfProducts++; } //projections and openings have already been applied, var toIgnore = new short[4]; toIgnore[0] = model.Metadata.ExpressTypeId("IFCOPENINGELEMENT"); toIgnore[1] = model.Metadata.ExpressTypeId("IFCPROJECTIONELEMENT"); if (model.SchemaVersion == XbimSchemaVersion.Ifc4 || model.SchemaVersion == XbimSchemaVersion.Ifc4x1) { toIgnore[2] = model.Metadata.ExpressTypeId("IFCVOIDINGFEATURE"); toIgnore[3] = model.Metadata.ExpressTypeId("IFCSURFACEFEATURE"); } foreach (var geometry in lookup) { if (geometry.ShapeData.Length <= 0) //no geometry to display so don't write out any products for it { continue; } var instances = geomRead.ShapeInstancesOfGeometry(geometry.ShapeLabel); var xbimShapeInstances = instances.Where(si => !toIgnore.Contains(si.IfcTypeId) && si.RepresentationType == XbimGeometryRepresentationType .OpeningsAndAdditionsIncluded && prodIds.Contains(si.IfcProductLabel)).ToList(); if (!xbimShapeInstances.Any()) { continue; } numberOfGeometries++; binaryStream.Write(xbimShapeInstances.Count); //the number of repetitions of the geometry if (xbimShapeInstances.Count > 1) { foreach (IXbimShapeInstanceData xbimShapeInstance in xbimShapeInstances) //write out each of the ids style and transforms { binaryStream.Write(xbimShapeInstance.IfcProductLabel); binaryStream.Write((UInt16)xbimShapeInstance.IfcTypeId); binaryStream.Write((UInt32)xbimShapeInstance.InstanceLabel); binaryStream.Write((Int32)xbimShapeInstance.StyleLabel > 0 ? xbimShapeInstance.StyleLabel : xbimShapeInstance.IfcTypeId * -1); var transformation = Translate(XbimMatrix3D.FromArray(xbimShapeInstance.Transformation), translation); binaryStream.Write(transformation.ToArray()); numberOfTriangles += XbimShapeTriangulation.TriangleCount(((IXbimShapeGeometryData)geometry).ShapeData); numberOfMatrices++; } numberOfVertices += XbimShapeTriangulation.VerticesCount(((IXbimShapeGeometryData)geometry).ShapeData); // binaryStream.Write(geometry.ShapeData); var ms = new MemoryStream(((IXbimShapeGeometryData)geometry).ShapeData); var br = new BinaryReader(ms); var tr = br.ReadShapeTriangulation(); tr.Write(binaryStream); } else //now do the single instances { var xbimShapeInstance = xbimShapeInstances[0]; // IXbimShapeGeometryData geometry = ShapeGeometry(kv.Key); binaryStream.Write((Int32)xbimShapeInstance.IfcProductLabel); binaryStream.Write((UInt16)xbimShapeInstance.IfcTypeId); binaryStream.Write((Int32)xbimShapeInstance.InstanceLabel); binaryStream.Write((Int32)xbimShapeInstance.StyleLabel > 0 ? xbimShapeInstance.StyleLabel : xbimShapeInstance.IfcTypeId * -1); //Read all vertices and normals in the geometry stream and transform var ms = new MemoryStream(((IXbimShapeGeometryData)geometry).ShapeData); var br = new BinaryReader(ms); var tr = br.ReadShapeTriangulation(); var transformation = Translate(xbimShapeInstance.Transformation, translation); var trTransformed = tr.Transform(transformation); trTransformed.Write(binaryStream); numberOfTriangles += XbimShapeTriangulation.TriangleCount(((IXbimShapeGeometryData)geometry).ShapeData); numberOfVertices += XbimShapeTriangulation.VerticesCount(((IXbimShapeGeometryData)geometry).ShapeData); } } binaryStream.Seek(start, SeekOrigin.Begin); binaryStream.Write((Int32)numberOfGeometries); binaryStream.Write((Int32)numberOfVertices); binaryStream.Write((Int32)numberOfTriangles); binaryStream.Write((Int32)numberOfMatrices); binaryStream.Write((Int32)numberOfProducts); binaryStream.Seek(0, SeekOrigin.End); //go back to end // ReSharper restore RedundantCast } }
public static void ReadWexbim(string fileName) { Vector3 offset; using (var fs = new FileStream(fileName, FileMode.Open, FileAccess.Read)) { using (var br = new BinaryReader(fs)) { var magicalNum = br.ReadInt32(); var version = br.ReadByte(); var shapeCount = br.ReadInt32(); var vertexCount = br.ReadInt32(); var triangleCount = br.ReadInt32(); var matrixCount = br.ReadInt32(); var productCount = br.ReadInt32(); var styleCount = br.ReadInt32(); var meter = br.ReadSingle(); var regionCount = br.ReadInt16(); for (int i = 0; i < regionCount; i++) { var population = br.ReadInt32(); var centreX = br.ReadSingle(); centreX /= meter; var centreY = br.ReadSingle(); centreY /= meter; var centreZ = br.ReadSingle(); centreZ /= meter; var boundsBytes = br.ReadBytes(6 * sizeof(float)); var modelBounds = XbimRect3D.FromArray(boundsBytes); modelBounds.X /= meter; modelBounds.Y /= meter; modelBounds.Z /= meter; modelBounds.SizeX /= meter; modelBounds.SizeY /= meter; modelBounds.SizeZ /= meter; BimGeomorty.regions.Add(new BimRegion(population, centreX, centreY, centreZ, (float)modelBounds.SizeX, (float)modelBounds.SizeY, (float)modelBounds.SizeZ)); } //中心偏移 offset = BimGeomorty.regions[0].position; for (int i = 0; i < styleCount; i++) { var styleId = br.ReadInt32(); var red = br.ReadSingle(); var green = br.ReadSingle(); var blue = br.ReadSingle(); var alpha = br.ReadSingle(); BimGeomorty.styles.Add(new BimStyle(styleId, red, green, blue, alpha)); } for (int i = 0; i < productCount; i++) { var productLabel = br.ReadInt32(); var productType = br.ReadInt16(); var boxBytes = br.ReadBytes(6 * sizeof(float)); XbimRect3D bb = XbimRect3D.FromArray(boxBytes); BimGeomorty.products.Add(new BimProduct(productLabel, productType)); } for (int i = 0; i < shapeCount; i++) { var shapeRepetition = br.ReadInt32(); BimShapeInstance shapeInstance; if (shapeRepetition > 1) { List <BimShapeInstance> tempInstances = new List <BimShapeInstance>(); for (int j = 0; j < shapeRepetition; j++) { var ifcProductLabel = br.ReadInt32(); var ifcTypeId = br.ReadInt16(); var instanceLabel = br.ReadInt32(); var styleLabel = br.ReadInt32(); var transform = XbimMatrix3D.FromArray(br.ReadBytes(sizeof(double) * 16)); shapeInstance = new BimShapeInstance(ifcProductLabel, ifcTypeId, instanceLabel, styleLabel, transform); BimGeomorty.shapeInstances.Add(shapeInstance); tempInstances.Add(shapeInstance); var p = BimGeomorty.products.Find(product => product.productLabel == ifcProductLabel); p.AddShapeInstance(shapeInstance); } var triangulation = br.ReadShapeTriangulation(); foreach (var temp in tempInstances) { var tri = new BimTriangulation(triangulation, offset, meter, temp.xbimMatrix, true); temp.AddTriangulation(tri); BimGeomorty.triangulations.Add(tri); } } else if (shapeRepetition == 1) { var ifcProductLabel = br.ReadInt32(); var ifcTypeId = br.ReadInt16(); var instanceLabel = br.ReadInt32(); var styleLabel = br.ReadInt32(); shapeInstance = new BimShapeInstance(ifcProductLabel, ifcTypeId, instanceLabel, styleLabel); BimGeomorty.shapeInstances.Add(shapeInstance); var p = BimGeomorty.products.Find(product => product.productLabel == ifcProductLabel); p.AddShapeInstance(shapeInstance); XbimShapeTriangulation triangulation = br.ReadShapeTriangulation(); var tri = new BimTriangulation(triangulation, offset, meter); BimGeomorty.triangulations.Add(tri); shapeInstance.AddTriangulation(tri); } } } } }
private static void composetrianglesets(XbimFaceTriangulation face, XbimShapeTriangulation shapemesh, int entityLabel, int Number_Faces, int face_index, int triangle_Count, int number_of_shapes) { Dictionary <string, List <int> > triangles = new Dictionary <string, List <int> >(); Dictionary <string, XbimPoint3D> vertices = new Dictionary <string, XbimPoint3D>(); List <XbimPoint3D> verts = shapemesh.Vertices.ToList(); //write each face with its ID xmlWriter.WriteStartElement("Face"); xmlWriter.WriteAttributeString("ID", face_index.ToString()); //write the Triangles with its number for each face xmlWriter.WriteStartElement("Triangles"); xmlWriter.WriteAttributeString("NumTriangles", triangle_Count.ToString()); //for (int i = 0; i < verts.Count(); i++) //{ // string name = "vertex_" + (i).ToString(); // vertices.Add(name, verts[i]); //} //foreach (var v in vertices) //{ // Console.WriteLine($"{GetIndent(15)}{v.Key + ": "}{v.Value.X + ", "}{v.Value.Y + ", "}{v.Value.Z}"); //} /*******************************************************************************************************/ for (int i = 0; i < face.TriangleCount; i++) { string name = "triangle_" + (i + 1).ToString(); triangles.Add(name, face.Indices.ToList().GetRange(i * 3, 3)); } //for the id of the triangle int triangle_index = 0; foreach (var x in triangles) { //writing each triangle with his ID xmlWriter.WriteStartElement("Triangle"); xmlWriter.WriteAttributeString("ID", triangle_index.ToString()); var vert1 = x.Value[0]; var vert2 = x.Value[1]; var vert3 = x.Value[2]; Console.WriteLine($"{"\n"}{GetIndent(15)}{x.Key + ": "}{vert1 + ","}{vert2 + ","}{vert3}"); Console.WriteLine($"{GetIndent(15)}{"---------------------"}"); //writing the vertices element with its count xmlWriter.WriteStartElement("Vertices"); xmlWriter.WriteAttributeString("NumVertices", "3"); Double X; Double Y; Double Z; for (int y = 0; y < x.Value.Count(); y++) { //get the vertice index(ID) and its x,y,z var vertice_index = x.Value[y]; X = Math.Round((double)verts[x.Value[y]].X, 2); Y = Math.Round((double)verts[x.Value[y]].Y, 2); Z = Math.Round((double)verts[x.Value[y]].Z, 2); Console.WriteLine($"{GetIndent(15)}{vertice_index.ToString() + ": "}{X}{"|"}{Y}{"|"}{Z}"); //writing in the xml file xmlWriter.WriteStartElement("Vertice"); xmlWriter.WriteAttributeString("ID", vertice_index.ToString()); xmlWriter.WriteElementString("X", X.ToString()); xmlWriter.WriteElementString("Y", Y.ToString()); xmlWriter.WriteElementString("Z", Z.ToString()); //this is for the vertice_index xmlWriter.WriteEndElement(); } //this is for the vertices xmlWriter.WriteEndElement(); //this is for the triangle id xmlWriter.WriteEndElement(); triangle_index++; } //this is for the triangle Number xmlWriter.WriteEndElement(); //this is for the face id xmlWriter.WriteEndElement(); }
void Awake() { Material true_mat = new Material(Shader.Find("Standard")); GameObject parent = new GameObject("WexbimModel"); GameObject go; Mesh mesh; const string fileName = "IFCBuilding"; using (var fs = new FileStream(fileName + ".wexBIM", FileMode.Open, FileAccess.Read)) { using (var br = new BinaryReader(fs)) { var magicNumber = br.ReadInt32(); if (magicNumber != 94132117) { throw new ArgumentException("Magic number mismatch."); } // Assert.IsTrue(magicNumber == IfcStore.WexBimId); var version = br.ReadByte(); var shapeCount = br.ReadInt32(); var vertexCount = br.ReadInt32(); var triangleCount = br.ReadInt32(); var matrixCount = br.ReadInt32(); var productCount = br.ReadInt32(); var styleCount = br.ReadInt32(); var meter = br.ReadSingle(); // Assert.IsTrue(meter > 0); var regionCount = br.ReadInt16(); for (int i = 0; i < regionCount; i++) { var population = br.ReadInt32(); var centreX = br.ReadSingle(); var centreY = br.ReadSingle(); var centreZ = br.ReadSingle(); var boundsBytes = br.ReadBytes(6 * sizeof(float)); var modelBounds = XbimRect3D.FromArray(boundsBytes); } for (int i = 0; i < styleCount; i++) { var styleId = br.ReadInt32(); var red = br.ReadSingle(); var green = br.ReadSingle(); var blue = br.ReadSingle(); var alpha = br.ReadSingle(); true_mat.SetColor(styleId, new Color(red, green, blue, alpha)); } for (int i = 0; i < productCount; i++) { var productLabel = br.ReadInt32(); var productType = br.ReadInt16(); var boxBytes = br.ReadBytes(6 * sizeof(float)); XbimRect3D bb = XbimRect3D.FromArray(boxBytes); //is this the factor to magnify/demise an ifcproduct? // Debug.Log("product Label: " + productLabel + " ,productType: " + productType); } for (int i = 0; i < shapeCount; i++) { var shapeRepetition = br.ReadInt32(); // Assert.IsTrue(shapeRepetition > 0); if (shapeRepetition > 1) { GameObject[] repes = new GameObject[shapeRepetition]; int[] ColorStyleId = new int[shapeRepetition]; for (int j = 0; j < shapeRepetition; j++) { var ifcProductLabel = br.ReadInt32(); var instanceTypeId = br.ReadInt16(); var instanceLabel = br.ReadInt32(); var styleId = br.ReadInt32(); var transform = XbimMatrix3D.FromArray(br.ReadBytes(sizeof(double) * 16)); // Debug.Log("ifcProductLabel: " + ifcProductLabel+ " ,instanceTypeId: " + instanceTypeId + " ,instanceLabel: " + instanceLabel); go = new GameObject(ifcProductLabel.ToString()); go.transform.parent = parent.transform; repes[j] = go; //order of ro/po makes no diference go.transform.rotation = new Quaternion(Flo_convert(transform.GetRotationQuaternion().X), Flo_convert(transform.GetRotationQuaternion().Y), Flo_convert(transform.GetRotationQuaternion().Z), Flo_convert(transform.GetRotationQuaternion().W)); go.transform.position = new Vector3(Flo_convert(transform.Translation.X / meter), Flo_convert(transform.Translation.Y / meter), Flo_convert(transform.Translation.Z / meter)); ColorStyleId[j] = styleId; } var triangulation = br.ReadShapeTriangulation(); int TriangleIndexCount = 0; foreach (var face in triangulation.Faces) { foreach (var triIndex in face.Indices) { ++TriangleIndexCount; } } int VerticesCount = triangulation.Vertices.Count; int FaceCount = triangulation.Faces.Count; Vector3[] vertices = new Vector3[VerticesCount]; //these eventully write into unity gameobject int[] triangleIndices = new int[TriangleIndexCount]; int TriangleIndex = 0; for (int j = 0; j < VerticesCount; j++) { var vert = new Vector3(Flo_convert(triangulation.Vertices[j].X), Flo_convert(triangulation.Vertices[j].Y), Flo_convert(triangulation.Vertices[j].Z)); vertices[j] = vert / meter; } for (int j = 0; j < FaceCount; j++) { for (int k = 0; k < triangulation.Faces[j].Indices.Count; k++) { triangleIndices[TriangleIndex++] = triangulation.Faces[j].Indices[k]; } } foreach (var repete in repes) { int id = 0; repete.AddComponent <MeshFilter>(); repete.AddComponent <MeshRenderer>(); mesh = new Mesh(); repete.GetComponent <MeshFilter>().mesh = mesh; MeshRenderer meshRenderer = repete.GetComponent <MeshRenderer>(); meshRenderer.material.color = true_mat.GetColor(ColorStyleId[id++]); mesh.vertices = vertices;// in unity vertices must defined before triangles mesh.triangles = triangleIndices; mesh.RecalculateNormals(); repete.AddComponent <MeshCollider>(); } // Assert.IsTrue(triangulation.Vertices.Count > 0, "Number of vertices should be greater than zero"); } else if (shapeRepetition == 1) { var ifcProductLabel = br.ReadInt32(); var instanceTypeId = br.ReadInt16(); var instanceLabel = br.ReadInt32(); var styleId = br.ReadInt32(); XbimShapeTriangulation triangulation = br.ReadShapeTriangulation(); // Assert.IsTrue(triangulation.Vertices.Count > 0, "Number of vertices should be greater than zero"); //Debug.Log("ifcProductLabel: " + ifcProductLabel + " ,instanceTypeId: " + instanceTypeId + " ,instanceLabel: " + instanceLabel); go = new GameObject(ifcProductLabel.ToString()); go.transform.parent = parent.transform; mesh = new Mesh(); go.AddComponent <MeshFilter>(); go.AddComponent <MeshRenderer>(); go.GetComponent <MeshFilter>().mesh = mesh; MeshRenderer meshRenderer = go.GetComponent <MeshRenderer>(); meshRenderer.material.color = true_mat.GetColor(styleId); int TriangleIndexCount = 0; int TriangleIndex = 0; foreach (var face in triangulation.Faces) { foreach (var triIndex in face.Indices) { ++TriangleIndexCount; } } int VerticesCount = triangulation.Vertices.Count; int FaceCount = triangulation.Faces.Count; Vector3[] vertices = new Vector3[VerticesCount]; //these eventully write into unity gameobject int[] triangleIndices = new int[TriangleIndexCount]; for (int j = 0; j < VerticesCount; j++) { vertices[j] = new Vector3(Flo_convert(triangulation.Vertices[j].X), Flo_convert(triangulation.Vertices[j].Y), Flo_convert(triangulation.Vertices[j].Z)); vertices[j] /= meter; } mesh.vertices = vertices; for (int j = 0; j < FaceCount; j++) { for (int k = 0; k < triangulation.Faces[j].Indices.Count; k++) { triangleIndices[TriangleIndex++] = triangulation.Faces[j].Indices[k]; } } mesh.triangles = triangleIndices; mesh.RecalculateNormals(); go.AddComponent <MeshCollider>(); } } } } Debug.Log("finish start meathod"); }