//private void WriteInstances(JsonWriter writer) //{ // //write a flag node for all pickable instances // writer.WriteStartObject(); // writer.WritePropertyName("type"); //instance node // writer.WriteValue("matrix"); // writer.WritePropertyName("id"); // writer.WriteValue("instances"); // writer.WritePropertyName("elements"); // // WriteMatrix(writer, GetGlobalModelTransform()); // WriteMatrix(writer, XbimMatrix3D.Identity); // writer.WritePropertyName("nodes"); // writer.WriteStartArray(); // WriteGeometry(writer); // writer.WriteEndArray(); // writer.WriteEndObject(); //} private void WriteInstances(JsonWriter writer) { XbimMatrix3D globalTrans = GetGlobalModelTransform(); //write out the material nodes and then the instances for each material // Dictionary<int, XbimTexture> styles = _context.SurfaceStyles().ToDictionary(s => s.DefinedObjectId); //write all pickable instances writer.WriteStartObject(); foreach (var shapeGeom in _context.ShapeGeometries()) { writer.WriteRaw(shapeGeom.ShapeData); //the vertex geometry writer.WritePropertyName("Shapes"); //instance nodes writer.WriteStartArray(); foreach (var shapeInstance in _context.ShapeInstancesOf(shapeGeom)) { writer.WriteStartObject(); writer.WritePropertyName("id"); writer.WriteValue(shapeInstance.InstanceLabel); writer.WritePropertyName("pid"); writer.WriteValue(shapeInstance.IfcProductLabel); writer.WritePropertyName("tr"); WriteMatrix(writer, shapeInstance.Transformation); writer.WritePropertyName("sid"); writer.WriteValue(shapeInstance.StyleLabel); writer.WriteEndObject(); } writer.WriteEndArray(); } writer.WriteEndObject(); }
public static SceneBuilder ToGltf(IfcStore model) { var context = new Xbim3DModelContext(model); context.CreateContext(); var geoms = context.ShapeGeometries().ToList(); Console.WriteLine("Number of geometries: " + geoms.Count); var mesh = new MeshBuilder <VERTEX>("mesh"); var material1 = new MaterialBuilder() .WithDoubleSide(true) .WithMetallicRoughnessShader() .WithChannelParam("BaseColor", new Vector4(1, 0, 0, 1)); foreach (var geom in geoms) { var data = ((IXbimShapeGeometryData)geom).ShapeData; using var stream = new MemoryStream(data); using var reader = new BinaryReader(stream); var meshBim = reader.ReadShapeTriangulation(); foreach (var face in meshBim.Faces) { var indeces = face.Indices; for (var triangle = 0; triangle < face.TriangleCount; triangle++) { var start = triangle * 3; var p0 = meshBim.Vertices[indeces[start]]; var p1 = meshBim.Vertices[indeces[start + 1]]; var p2 = meshBim.Vertices[indeces[start + 2]]; var prim = mesh.UsePrimitive(material1); prim.AddTriangle( new VERTEX((float)p0.X, (float)p0.Y, (float)p0.Z * 10), new VERTEX((float)p1.X, (float)p1.Y, (float)p1.Z * 10), new VERTEX((float)p2.X, (float)p2.Y, (float)p2.Z * 10)); } } } var scene = new SceneBuilder(); scene.AddRigidMesh(mesh, Matrix4x4.Identity); return(scene); }
public void TestShapeGeometriesEnumerability() { using (var model = new XbimModel()) { model.Open(@"EsentTestFiles\TwoWalls.xbim"); var geomContext = new Xbim3DModelContext(model); var lst = new Dictionary <int, int>(); // ShapeGeometries does not have duplicates... lst.Clear(); foreach (var g1 in geomContext.ShapeGeometries()) { lst.Add(g1.ShapeLabel, g1.IfcShapeLabel); } // ... so it shouldn't even through the ToArray() function. lst.Clear(); foreach (var g1 in geomContext.ShapeGeometries().ToArray()) { lst.Add(g1.ShapeLabel, g1.IfcShapeLabel); } } }
/// <summary> /// This version uses the new Geometry representation /// </summary> /// <param name="model"></param> /// <param name="context"></param> /// <param name="exclude">List of type to exclude, by default excplict openings and spaces are excluded if exclude = null</param> /// <returns></returns> private void BuildScene(Xbim3DModelContext context) { //get a list of all the unique styles Dictionary<int, WpfMaterial> styles = new Dictionary<int, WpfMaterial>(); Dictionary<int, MeshGeometry3D> shapeGeometries = new Dictionary<int, MeshGeometry3D>(); Dictionary<int, WpfMeshGeometry3D> meshSets = new Dictionary<int, WpfMeshGeometry3D>(); Model3DGroup opaques = new Model3DGroup(); Model3DGroup transparents = new Model3DGroup(); foreach (var shapeGeom in context.ShapeGeometries()) { MeshGeometry3D wpfMesh = new MeshGeometry3D(); wpfMesh.SetValue(TagProperty, shapeGeom); //don't read the geometry into the mesh yet as we do not know where the instance is located shapeGeometries.Add(shapeGeom.ShapeLabel, wpfMesh); } foreach (var style in context.SurfaceStyles()) { WpfMaterial wpfMaterial = new WpfMaterial(); wpfMaterial.CreateMaterial(style); styles.Add(style.DefinedObjectId, wpfMaterial); WpfMeshGeometry3D mg = new WpfMeshGeometry3D(wpfMaterial, wpfMaterial); meshSets.Add(style.DefinedObjectId, mg); if (style.IsTransparent) transparents.Children.Add(mg); else opaques.Children.Add(mg); } ////if (!styles.Any()) return ; //this should always have something unless the model is empty ////double metre = model.ModelFactors.OneMetre; ////XbimMatrix3D wcsTransform = XbimMatrix3D.CreateTranslation(_modelTranslation) * XbimMatrix3D.CreateScale((float)(1 / metre)); ////foreach (var shapeInstance in context.ShapeInstances() //// .Where(s => s.RepresentationType == XbimGeometryRepresentationType.OpeningsAndAdditionsIncluded && //// !typeof(IfcFeatureElement).IsAssignableFrom(IfcMetaData.GetType(s.IfcTypeId)) && //// !typeof(IfcSpace).IsAssignableFrom(IfcMetaData.GetType(s.IfcTypeId)))) ////{ //// int styleId = shapeInstance.StyleLabel > 0 ? shapeInstance.StyleLabel : shapeInstance.IfcTypeId * -1; //// //GET THE ACTUAL GEOMETRY //// MeshGeometry3D wpfMesh; //// //see if we have already read it //// if (shapeGeometries.TryGetValue(shapeInstance.ShapeGeometryLabel, out wpfMesh)) //// { //// GeometryModel3D mg = new GeometryModel3D(wpfMesh, styles[styleId]); //// mg.SetValue(TagProperty, new XbimInstanceHandle(model, shapeInstance.IfcProductLabel, shapeInstance.IfcTypeId)); //// mg.BackMaterial = mg.Material; //// mg.Transform = XbimMatrix3D.Multiply(shapeInstance.Transformation, wcsTransform).ToMatrixTransform3D(); //// if (styles[styleId].IsTransparent) //// transparents.Children.Add(mg); //// else //// opaques.Children.Add(mg); //// } //// else //we need to get the shape geometry //// { //// XbimShapeGeometry shapeGeom = context.ShapeGeometry(shapeInstance.ShapeGeometryLabel); //// if (shapeGeom.ReferenceCount > 1) //only store if we are going to use again //// { //// wpfMesh = new MeshGeometry3D(); //// wpfMesh.Read(shapeGeom.ShapeData); //// shapeGeometries.Add(shapeInstance.ShapeGeometryLabel, wpfMesh); //// GeometryModel3D mg = new GeometryModel3D(wpfMesh, styles[styleId]); //// mg.SetValue(TagProperty, new XbimInstanceHandle(model, shapeInstance.IfcProductLabel, shapeInstance.IfcTypeId)); //// mg.BackMaterial = mg.Material; //// mg.Transform = XbimMatrix3D.Multiply(shapeInstance.Transformation, wcsTransform).ToMatrixTransform3D(); //// if (styles[styleId].IsTransparent) //// transparents.Children.Add(mg); //// else //// opaques.Children.Add(mg); //// } //// else //it is a one off, merge it with shapes of a similar material //// { //// WpfMeshGeometry3D mg = meshSets[styleId]; //// mg.Add(shapeGeom.ShapeData, //// shapeInstance.IfcTypeId, //// shapeInstance.IfcProductLabel, //// shapeInstance.InstanceLabel, //// XbimMatrix3D.Multiply(shapeInstance.Transformation, wcsTransform), 0); //// } //// } ////} if (opaques.Children.Any()) { ModelVisual3D mv = new ModelVisual3D(); mv.Content = opaques; Opaques.Children.Add(mv); if (_modelBounds.IsEmpty) _modelBounds = mv.Content.Bounds.ToXbimRect3D(); else _modelBounds.Union(mv.Content.Bounds.ToXbimRect3D()); } if (transparents.Children.Any()) { ModelVisual3D mv = new ModelVisual3D(); mv.Content = transparents; Transparents.Children.Add(mv); if (_modelBounds.IsEmpty) _modelBounds = mv.Content.Bounds.ToXbimRect3D(); else _modelBounds.Union(mv.Content.Bounds.ToXbimRect3D()); } }
/// <summary> /// This version uses the new Geometry representation /// </summary> /// <param name="model"></param> /// <param name="context"></param> /// <param name="exclude">List of type to exclude, by default excplict openings and spaces are excluded if exclude = null</param> /// <returns></returns> private void BuildScene(Xbim3DModelContext context) { //get a list of all the unique styles Dictionary <int, WpfMaterial> styles = new Dictionary <int, WpfMaterial>(); Dictionary <int, MeshGeometry3D> shapeGeometries = new Dictionary <int, MeshGeometry3D>(); Dictionary <int, WpfMeshGeometry3D> meshSets = new Dictionary <int, WpfMeshGeometry3D>(); Model3DGroup opaques = new Model3DGroup(); Model3DGroup transparents = new Model3DGroup(); foreach (var shapeGeom in context.ShapeGeometries()) { MeshGeometry3D wpfMesh = new MeshGeometry3D(); wpfMesh.SetValue(TagProperty, shapeGeom); //don't read the geometry into the mesh yet as we do not know where the instance is located shapeGeometries.Add(shapeGeom.ShapeLabel, wpfMesh); } foreach (var style in context.SurfaceStyles()) { WpfMaterial wpfMaterial = new WpfMaterial(); wpfMaterial.CreateMaterial(style); styles.Add(style.DefinedObjectId, wpfMaterial); WpfMeshGeometry3D mg = new WpfMeshGeometry3D(wpfMaterial, wpfMaterial); meshSets.Add(style.DefinedObjectId, mg); if (style.IsTransparent) { transparents.Children.Add(mg); } else { opaques.Children.Add(mg); } } ////if (!styles.Any()) return ; //this should always have something unless the model is empty ////double metre = model.ModelFactors.OneMetre; ////XbimMatrix3D wcsTransform = XbimMatrix3D.CreateTranslation(_modelTranslation) * XbimMatrix3D.CreateScale((float)(1 / metre)); ////foreach (var shapeInstance in context.ShapeInstances() //// .Where(s => s.RepresentationType == XbimGeometryRepresentationType.OpeningsAndAdditionsIncluded && //// !typeof(IfcFeatureElement).IsAssignableFrom(IfcMetaData.GetType(s.IfcTypeId)) && //// !typeof(IfcSpace).IsAssignableFrom(IfcMetaData.GetType(s.IfcTypeId)))) ////{ //// int styleId = shapeInstance.StyleLabel > 0 ? shapeInstance.StyleLabel : shapeInstance.IfcTypeId * -1; //// //GET THE ACTUAL GEOMETRY //// MeshGeometry3D wpfMesh; //// //see if we have already read it //// if (shapeGeometries.TryGetValue(shapeInstance.ShapeGeometryLabel, out wpfMesh)) //// { //// GeometryModel3D mg = new GeometryModel3D(wpfMesh, styles[styleId]); //// mg.SetValue(TagProperty, new XbimInstanceHandle(model, shapeInstance.IfcProductLabel, shapeInstance.IfcTypeId)); //// mg.BackMaterial = mg.Material; //// mg.Transform = XbimMatrix3D.Multiply(shapeInstance.Transformation, wcsTransform).ToMatrixTransform3D(); //// if (styles[styleId].IsTransparent) //// transparents.Children.Add(mg); //// else //// opaques.Children.Add(mg); //// } //// else //we need to get the shape geometry //// { //// XbimShapeGeometry shapeGeom = context.ShapeGeometry(shapeInstance.ShapeGeometryLabel); //// if (shapeGeom.ReferenceCount > 1) //only store if we are going to use again //// { //// wpfMesh = new MeshGeometry3D(); //// wpfMesh.Read(shapeGeom.ShapeData); //// shapeGeometries.Add(shapeInstance.ShapeGeometryLabel, wpfMesh); //// GeometryModel3D mg = new GeometryModel3D(wpfMesh, styles[styleId]); //// mg.SetValue(TagProperty, new XbimInstanceHandle(model, shapeInstance.IfcProductLabel, shapeInstance.IfcTypeId)); //// mg.BackMaterial = mg.Material; //// mg.Transform = XbimMatrix3D.Multiply(shapeInstance.Transformation, wcsTransform).ToMatrixTransform3D(); //// if (styles[styleId].IsTransparent) //// transparents.Children.Add(mg); //// else //// opaques.Children.Add(mg); //// } //// else //it is a one off, merge it with shapes of a similar material //// { //// WpfMeshGeometry3D mg = meshSets[styleId]; //// mg.Add(shapeGeom.ShapeData, //// shapeInstance.IfcTypeId, //// shapeInstance.IfcProductLabel, //// shapeInstance.InstanceLabel, //// XbimMatrix3D.Multiply(shapeInstance.Transformation, wcsTransform), 0); //// } //// } ////} if (opaques.Children.Any()) { ModelVisual3D mv = new ModelVisual3D(); mv.Content = opaques; Opaques.Children.Add(mv); if (_modelBounds.IsEmpty) { _modelBounds = mv.Content.Bounds.ToXbimRect3D(); } else { _modelBounds.Union(mv.Content.Bounds.ToXbimRect3D()); } } if (transparents.Children.Any()) { ModelVisual3D mv = new ModelVisual3D(); mv.Content = transparents; Transparents.Children.Add(mv); if (_modelBounds.IsEmpty) { _modelBounds = mv.Content.Bounds.ToXbimRect3D(); } else { _modelBounds.Union(mv.Content.Bounds.ToXbimRect3D()); } } }
/// <summary> /// Retrieves model metrics for future analysis /// </summary> /// <param name="args"></param> static void Main(string[] args) { Params arguments = Params.ParseParams(args); if (arguments.IsValid) { var metrics = new XbimModelMetrics(); using (var model = IfcStore.Open(arguments.SourceModelName)) { if (!arguments.SourceIsXbimFile) //need to parse the file { Console.WriteLine("Generating Geometry ..."); var m3D = new Xbim3DModelContext(model); m3D.CreateContext(); } Console.WriteLine("Analysing....."); metrics["Number Of IfcProducts"] = model.Instances.OfType <IfcProduct>().Count(); var shapeDefinitions = model.Instances.OfType <IfcProductDefinitionShape>().ToList(); metrics["Number Of IfcProductDefinitionShape"] = shapeDefinitions.Count(); var rep = shapeDefinitions.SelectMany(shape => shape.Representations.SelectMany(a => a.Items)); //.Where(s=>s.IsSolidModel())); metrics["Number Of Shape Items"] = rep.Count(); metrics["Number Of IfcCartesianPoint"] = model.Instances.OfType <IfcCartesianPoint>().Count(); metrics["Number Of IfcFaceBasedSurfaceModel"] = model.Instances.OfType <IfcFaceBasedSurfaceModel>().Count(); metrics["Number Of IfcShellBasedSurfaceModel"] = model.Instances.OfType <IfcShellBasedSurfaceModel>().Count(); metrics["Number Of IfcSolidModel"] = model.Instances.OfType <IfcSolidModel>().Count(); metrics["Number Of IfcHalfSpaceSolid"] = model.Instances.OfType <IfcHalfSpaceSolid>().Count(); metrics["Number Of IfcBooleanResult"] = model.Instances.OfType <IfcBooleanResult>().Count(); metrics["Number Of IfcMappedItem"] = model.Instances.OfType <IfcMappedItem>().Count(); double totalVoids = 0; double maxVoidsPerElement = 0; double totalElements = 0; foreach (var relVoids in model.Instances.OfType <IfcRelVoidsElement>().GroupBy(r => r.RelatingBuildingElement)) { var voidCount = relVoids.Count(); totalVoids += voidCount; totalElements++; double newmaxVoidsPerElement = Math.Max(maxVoidsPerElement, voidCount); if (newmaxVoidsPerElement != maxVoidsPerElement) { maxVoidsPerElement = newmaxVoidsPerElement; Console.WriteLine("Element is #{0}", relVoids.Key.EntityLabel); } } metrics["Total Of Openings Cut"] = totalVoids; metrics["Number Of Element with Openings"] = totalElements; metrics["Maximum openings in an Element"] = maxVoidsPerElement; metrics["Average openings in an Element"] = totalVoids == 0 ? 0.0 : totalElements / totalVoids; //if the model has shape geometry report on that var context = new Xbim3DModelContext(model); metrics["Number of Shape Geometries"] = context.ShapeGeometries().Count(); metrics["Number of Shape Instances"] = context.ShapeInstances().Count(); // metrics["Number of Surface Styles"] = context.().Count(); model.Close(); } foreach (var metric in metrics) { Console.WriteLine("{0} = {1}", metric.Key, metric.Value); } } Console.WriteLine("Press Enter to continue..."); Console.ReadLine(); }
public void TestShapeGeometriesEnumerability() { using (var model = new XbimModel()) { model.Open(@"EsentTestFiles\TwoWalls.xbim"); var geomContext = new Xbim3DModelContext(model); var lst = new Dictionary<int, int>(); // ShapeGeometries does not have duplicates... lst.Clear(); foreach (var g1 in geomContext.ShapeGeometries()) { lst.Add(g1.ShapeLabel, g1.IfcShapeLabel); } // ... so it shouldn't even through the ToArray() function. lst.Clear(); foreach (var g1 in geomContext.ShapeGeometries().ToArray()) { lst.Add(g1.ShapeLabel, g1.IfcShapeLabel); } } }