/// <summary> /// Generate a Scene /// </summary> /// <param name="model"></param> /// <returns></returns> public XbimScene <XbimMeshGeometry3D, WpfMaterial> GetModelScene(XbimModel model) { //we need a class which implements IXbimRenderMaterial for the material, you might also want to implement a class for Material depending on your needs, //using the WpfMaterial class that then used the Media3D material class as implemented by the XBimXplorer for convenience. XbimScene <XbimMeshGeometry3D, WpfMaterial> scene = new XbimScene <XbimMeshGeometry3D, WpfMaterial>(model); XbimGeometryHandleCollection handles = new XbimGeometryHandleCollection(model.GetGeometryHandles() .Exclude(IfcEntityNameEnum.IFCFEATUREELEMENT)); foreach (var layerContent in handles.GroupByBuildingElementTypes()) { string elementTypeName = layerContent.Key; XbimGeometryHandleCollection layerHandles = layerContent.Value; IEnumerable <XbimGeometryData> geomColl = model.GetGeometryData(layerHandles); XbimColour colour = scene.LayerColourMap[elementTypeName]; XbimMeshLayer <XbimMeshGeometry3D, WpfMaterial> layer = new XbimMeshLayer <XbimMeshGeometry3D, WpfMaterial>(model, colour) { Name = elementTypeName }; //add all content initially into the hidden field foreach (var geomData in geomColl) { layer.AddToHidden(geomData, model); } scene.Add(layer); } return(scene); }
public XbimMeshLayer<WpfMeshGeometry3D, WpfMaterial> GetLayer( string layerKey, XbimModel model, XbimScene<WpfMeshGeometry3D, WpfMaterial> scene ) { XbimColour colour = _colours[layerKey]; return new XbimMeshLayer<WpfMeshGeometry3D, WpfMaterial>(model, colour) { Name = layerKey }; }
public XbimMeshLayer<WpfMeshGeometry3D, WpfMaterial> GetLayer(string layerKey, XbimModel model, XbimScene<WpfMeshGeometry3D, WpfMaterial> scene) { if (layerKey == "Even") { XbimColour colour = new XbimColour("Red", 1.0, 0.0, 0.0, 1); return new XbimMeshLayer<WpfMeshGeometry3D, WpfMaterial>(model, colour) { Name = layerKey }; } else { XbimColour colour = new XbimColour("Green", 0.0, 1.0, 0.0, 1); return new XbimMeshLayer<WpfMeshGeometry3D, WpfMaterial>(model, colour) { Name = layerKey }; } }
public XbimMeshLayer <WpfMeshGeometry3D, WpfMaterial> GetLayer( string layerKey, XbimModel model, XbimScene <WpfMeshGeometry3D, WpfMaterial> scene ) { XbimColour colour = _colours[layerKey]; return(new XbimMeshLayer <WpfMeshGeometry3D, WpfMaterial>(model, colour) { Name = layerKey }); }
public ModelGeometry.Scene.XbimMeshLayer<WpfMeshGeometry3D, WpfMaterial> GetLayer( string layerKey, XbimModel model, XbimScene<WpfMeshGeometry3D, WpfMaterial> scene ) { int iLab; string LayerName = layerKey; bool conversionok = Int32.TryParse(layerKey, out iLab); if (conversionok) { layerKey = model.Instances[Math.Abs(iLab)].GetType().Name; } XbimColour colour = scene.LayerColourMap[layerKey]; return new XbimMeshLayer<WpfMeshGeometry3D, WpfMaterial>(model, colour) { Name = LayerName }; }
/// <summary> /// Create the geometry file (xbimGC file) /// </summary> /// <param name="cacheFile">file path to write file too</param> private void GenerateGeometry(string cacheFile) { //get all products for this model to place into the return graph, can filter here if required IEnumerable <IfcProduct> toDraw = Model.IfcProducts.Items; //Create the XBimScene which helps builds the file XbimScene scene = new XbimScene(Model, toDraw); //create the geometry file using (FileStream sceneStream = new FileStream(cacheFile, FileMode.Create, FileAccess.ReadWrite)) { BinaryWriter bw = new BinaryWriter(sceneStream); //show current status to user via ReportProgressDelegate Console.Clear(); scene.Graph.Write(bw, delegate(int percentProgress, object userState) { Console.Write("\rCreating GC File {0}", percentProgress); }); bw.Flush(); } }
/// <summary> /// Create the geometry file (xbimGC file) /// </summary> /// <param name="cacheFile">file path to write file too</param> private void GenerateGeometry(string cacheFile) { //get all products for this model to place into the return graph, can filter here if required IEnumerable<IfcProduct> toDraw = Model.IfcProducts.Items; //Create the XBimScene which helps builds the file XbimScene scene = new XbimScene(Model, toDraw); //create the geometry file using (FileStream sceneStream = new FileStream(cacheFile, FileMode.Create, FileAccess.ReadWrite)) { BinaryWriter bw = new BinaryWriter(sceneStream); //show current status to user via ReportProgressDelegate Console.Clear(); scene.Graph.Write(bw, delegate(int percentProgress, object userState) { Console.Write("\rCreating GC File {0}", percentProgress); }); bw.Flush(); } }
public ModelGeometry.Scene.XbimMeshLayer <WpfMeshGeometry3D, WpfMaterial> GetLayer( string layerKey, XbimModel model, XbimScene <WpfMeshGeometry3D, WpfMaterial> scene ) { int iLab; string LayerName = layerKey; bool conversionok = Int32.TryParse(layerKey, out iLab); if (conversionok) { layerKey = model.Instances[iLab].GetType().Name; } XbimColour colour = scene.LayerColourMap[layerKey]; return(new XbimMeshLayer <WpfMeshGeometry3D, WpfMaterial>(model, colour) { Name = LayerName }); }
/// <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> public XbimScene <WpfMeshGeometry3D, WpfMaterial> BuildScene(XbimModel model, Xbim3DModelContext context, List <Type> exclude = null) { var excludedTypes = new HashSet <short>(); if (exclude == null) { exclude = new List <Type>() { typeof(IfcSpace) // , typeof(IfcFeatureElement) } } ; foreach (var excludedT in exclude) { var ifcT = IfcMetaData.IfcType(excludedT); foreach (var exIfcType in ifcT.NonAbstractSubTypes.Select(IfcMetaData.IfcType)) { excludedTypes.Add(exIfcType.TypeId); } } var scene = new XbimScene <WpfMeshGeometry3D, WpfMaterial>(model); if (context == null) { return(scene); } //get a list of all the unique styles var styles = new Dictionary <int, WpfMaterial>(); var repeatedShapeGeometries = new Dictionary <int, MeshGeometry3D>(); var styleMeshSets = new Dictionary <int, WpfMeshGeometry3D>(); var tmpOpaquesGroup = new Model3DGroup(); var tmpTransparentsGroup = new Model3DGroup(); var sstyles = context.SurfaceStyles(); foreach (var style in sstyles) { var wpfMaterial = new WpfMaterial(); wpfMaterial.CreateMaterial(style); styles.Add(style.DefinedObjectId, wpfMaterial); var mg = new WpfMeshGeometry3D(wpfMaterial, wpfMaterial); mg.WpfModel.SetValue(FrameworkElement.TagProperty, mg); styleMeshSets.Add(style.DefinedObjectId, mg); mg.BeginUpdate(); if (style.IsTransparent) { tmpTransparentsGroup.Children.Add(mg); } else { tmpOpaquesGroup.Children.Add(mg); } } if (!styles.Any()) { return(scene); //this should always return something } var shapeInstances = context.ShapeInstances() .Where(s => s.RepresentationType == XbimGeometryRepresentationType.OpeningsAndAdditionsIncluded && !excludedTypes.Contains(s.IfcTypeId)); // !typeof (IfcFeatureElement).IsAssignableFrom(IfcMetaData.GetType(s.IfcTypeId)) /*&& // !typeof(IfcSpace).IsAssignableFrom(IfcMetaData.GetType(s.IfcTypeId))*/); foreach (var shapeInstance in shapeInstances) { var styleId = shapeInstance.StyleLabel > 0 ? shapeInstance.StyleLabel : shapeInstance.IfcTypeId * -1; //GET THE ACTUAL GEOMETRY MeshGeometry3D wpfMesh; //see if we have already read it if (repeatedShapeGeometries.TryGetValue(shapeInstance.ShapeGeometryLabel, out wpfMesh)) { var mg = new GeometryModel3D(wpfMesh, styles[styleId]); mg.SetValue(FrameworkElement.TagProperty, new XbimInstanceHandle(model, shapeInstance.IfcProductLabel, shapeInstance.IfcTypeId)); mg.BackMaterial = mg.Material; mg.Transform = XbimMatrix3D.Multiply(shapeInstance.Transformation, Control.ModelPositions[model].Transfrom).ToMatrixTransform3D(); if (styles[styleId].IsTransparent) { tmpTransparentsGroup.Children.Add(mg); } else { tmpOpaquesGroup.Children.Add(mg); } } else //we need to get the shape geometry { IXbimShapeGeometryData shapeGeom = context.ShapeGeometry(shapeInstance.ShapeGeometryLabel); if (shapeGeom.ReferenceCount > 1) //only store if we are going to use again { wpfMesh = new MeshGeometry3D(); switch ((XbimGeometryType)shapeGeom.Format) { case XbimGeometryType.PolyhedronBinary: wpfMesh.Read(shapeGeom.ShapeData); break; case XbimGeometryType.Polyhedron: wpfMesh.Read(((XbimShapeGeometry)shapeGeom).ShapeData); break; } repeatedShapeGeometries.Add(shapeInstance.ShapeGeometryLabel, wpfMesh); var mg = new GeometryModel3D(wpfMesh, styles[styleId]); mg.SetValue(FrameworkElement.TagProperty, new XbimInstanceHandle(model, shapeInstance.IfcProductLabel, shapeInstance.IfcTypeId)); mg.BackMaterial = mg.Material; mg.Transform = XbimMatrix3D.Multiply(shapeInstance.Transformation, Control.ModelPositions[model].Transfrom).ToMatrixTransform3D(); if (styles[styleId].IsTransparent) { tmpTransparentsGroup.Children.Add(mg); } else { tmpOpaquesGroup.Children.Add(mg); } } else //it is a one off, merge it with shapes of a similar material { var targetMergeMeshByStyle = styleMeshSets[styleId]; switch ((XbimGeometryType)shapeGeom.Format) { case XbimGeometryType.Polyhedron: // var shapePoly = (XbimShapeGeometry)shapeGeom; var asString = Encoding.UTF8.GetString(shapeGeom.ShapeData.ToArray()); targetMergeMeshByStyle.Add( asString, shapeInstance.IfcTypeId, shapeInstance.IfcProductLabel, shapeInstance.InstanceLabel, XbimMatrix3D.Multiply(shapeInstance.Transformation, Control.ModelPositions[model].Transfrom), model.UserDefinedId); break; case XbimGeometryType.PolyhedronBinary: var transform = XbimMatrix3D.Multiply(shapeInstance.Transformation, Control.ModelPositions[model].Transfrom); targetMergeMeshByStyle.Add( shapeGeom.ShapeData, shapeInstance.IfcTypeId, shapeInstance.IfcProductLabel, shapeInstance.InstanceLabel, transform, model.UserDefinedId); break; default: throw new ArgumentOutOfRangeException(); } } } } foreach (var wpfMeshGeometry3D in styleMeshSets.Values) { wpfMeshGeometry3D.EndUpdate(); } //} if (tmpOpaquesGroup.Children.Any()) { var mv = new ModelVisual3D(); mv.Content = tmpOpaquesGroup; Control.OpaquesVisual3D.Children.Add(mv); // Control.ModelBounds = mv.Content.Bounds.ToXbimRect3D(); } if (tmpTransparentsGroup.Children.Any()) { var mv = new ModelVisual3D(); mv.Content = tmpTransparentsGroup; Control.TransparentsVisual3D.Children.Add(mv); //if (Control.ModelBounds.IsEmpty) Control.ModelBounds = mv.Content.Bounds.ToXbimRect3D(); //else Control.ModelBounds.Union(mv.Content.Bounds.ToXbimRect3D()); } return(scene); }
public XbimScene <WpfMeshGeometry3D, WpfMaterial> BuildScene(XbimModel model, Xbim3DModelContext context, List <Type> exclude = null) { var tmpOpaquesGroup = new Model3DGroup(); var retScene = new XbimScene <WpfMeshGeometry3D, WpfMaterial>(model); var red = PrepareMesh(new XbimColour("Red", 1.0, 0.0, 0.0, 0.5)); var green = PrepareMesh(new XbimColour("Green", 0.0, 1.0, 0.0, 0.5)); red.WpfModel.SetValue(FrameworkElement.TagProperty, red); green.WpfModel.SetValue(FrameworkElement.TagProperty, green); red.BeginUpdate(); green.BeginUpdate(); tmpOpaquesGroup.Children.Add(red); tmpOpaquesGroup.Children.Add(green); var i = 0; 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))*/)) { IXbimShapeGeometryData shapeGeom = context.ShapeGeometry(shapeInstance.ShapeGeometryLabel); WpfMeshGeometry3D targetMergeMesh; switch (i++ % 2) { case 0: targetMergeMesh = red; break; default: targetMergeMesh = green; break; } switch ((XbimGeometryType)shapeGeom.Format) { case XbimGeometryType.Polyhedron: var shapePoly = (XbimShapeGeometry)shapeGeom; targetMergeMesh.Add( shapePoly.ShapeData, shapeInstance.IfcTypeId, shapeInstance.IfcProductLabel, shapeInstance.InstanceLabel, XbimMatrix3D.Multiply(shapeInstance.Transformation, Control.ModelPositions[model].Transfrom), model.UserDefinedId); break; case XbimGeometryType.PolyhedronBinary: targetMergeMesh.Add( shapeGeom.ShapeData, shapeInstance.IfcTypeId, shapeInstance.IfcProductLabel, shapeInstance.InstanceLabel, XbimMatrix3D.Multiply(shapeInstance.Transformation, Control.ModelPositions[model].Transfrom), model.UserDefinedId ); break; default: throw new ArgumentOutOfRangeException(); } } red.EndUpdate(); green.EndUpdate(); var mv = new ModelVisual3D { Content = tmpOpaquesGroup }; Control.OpaquesVisual3D.Children.Add(mv); // Control.ModelBounds = mv.Content.Bounds.ToXbimRect3D(); return(retScene); }
/// <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> public XbimScene<WpfMeshGeometry3D, WpfMaterial> BuildScene(XbimModel model, Xbim3DModelContext context, List<Type> exclude = null) { var scene = new XbimScene<WpfMeshGeometry3D, WpfMaterial>(model); if (context == null) return scene; //get a list of all the unique styles var styles = new Dictionary<int, WpfMaterial>(); var repeatedShapeGeometries = new Dictionary<int, MeshGeometry3D>(); var styleMeshSets = new Dictionary<int, WpfMeshGeometry3D>(); var tmpOpaquesGroup = new Model3DGroup(); var tmpTransparentsGroup = new Model3DGroup(); var sstyles = context.SurfaceStyles(); foreach (var style in sstyles) { var wpfMaterial = new WpfMaterial(); wpfMaterial.CreateMaterial(style); styles.Add(style.DefinedObjectId, wpfMaterial); var mg = new WpfMeshGeometry3D(wpfMaterial, wpfMaterial); mg.WpfModel.SetValue(FrameworkElement.TagProperty, mg); styleMeshSets.Add(style.DefinedObjectId, mg); mg.BeginUpdate(); if (style.IsTransparent) tmpTransparentsGroup.Children.Add(mg); else tmpOpaquesGroup.Children.Add(mg); } if (!styles.Any()) return scene; //this should always return something int i = 0; var shapeInstances = context.ShapeInstances() .Where(s => s.RepresentationType == XbimGeometryRepresentationType.OpeningsAndAdditionsIncluded && !typeof (IfcFeatureElement).IsAssignableFrom(IfcMetaData.GetType(s.IfcTypeId)) /*&& !typeof(IfcSpace).IsAssignableFrom(IfcMetaData.GetType(s.IfcTypeId))*/); foreach (var shapeInstance in shapeInstances) { Console.WriteLine(i++); var styleId = shapeInstance.StyleLabel > 0 ? shapeInstance.StyleLabel : shapeInstance.IfcTypeId * -1; //GET THE ACTUAL GEOMETRY MeshGeometry3D wpfMesh; //see if we have already read it if (repeatedShapeGeometries.TryGetValue(shapeInstance.ShapeGeometryLabel, out wpfMesh)) { var mg = new GeometryModel3D(wpfMesh, styles[styleId]); mg.SetValue(FrameworkElement.TagProperty, new XbimInstanceHandle(model, shapeInstance.IfcProductLabel, shapeInstance.IfcTypeId)); mg.BackMaterial = mg.Material; mg.Transform = XbimMatrix3D.Multiply(shapeInstance.Transformation, Control.WcsTransform).ToMatrixTransform3D(); if (styles[styleId].IsTransparent) tmpTransparentsGroup.Children.Add(mg); else tmpOpaquesGroup.Children.Add(mg); } else //we need to get the shape geometry { IXbimShapeGeometryData shapeGeom = context.ShapeGeometry(shapeInstance.ShapeGeometryLabel); if (shapeGeom.ReferenceCount > 1) //only store if we are going to use again { wpfMesh = new MeshGeometry3D(); switch ((XbimGeometryType)shapeGeom.Format) { case XbimGeometryType.PolyhedronBinary: wpfMesh.Read(shapeGeom.ShapeData); break; case XbimGeometryType.Polyhedron: wpfMesh.Read(((XbimShapeGeometry)shapeGeom).ShapeData); break; } repeatedShapeGeometries.Add(shapeInstance.ShapeGeometryLabel, wpfMesh); var mg = new GeometryModel3D(wpfMesh, styles[styleId]); mg.SetValue(FrameworkElement.TagProperty, new XbimInstanceHandle(model, shapeInstance.IfcProductLabel, shapeInstance.IfcTypeId)); mg.BackMaterial = mg.Material; mg.Transform = XbimMatrix3D.Multiply(shapeInstance.Transformation, Control.WcsTransform).ToMatrixTransform3D(); if (styles[styleId].IsTransparent) tmpTransparentsGroup.Children.Add(mg); else tmpOpaquesGroup.Children.Add(mg); } else //it is a one off, merge it with shapes of a similar material { var targetMergeMeshByStyle = styleMeshSets[styleId]; switch ((XbimGeometryType)shapeGeom.Format) { case XbimGeometryType.Polyhedron: var shapePoly = (XbimShapeGeometry)shapeGeom; targetMergeMeshByStyle.Add( shapePoly.ShapeData, shapeInstance.IfcTypeId, shapeInstance.IfcProductLabel, shapeInstance.InstanceLabel, XbimMatrix3D.Multiply(shapeInstance.Transformation, Control.WcsTransform)); break; case XbimGeometryType.PolyhedronBinary: targetMergeMeshByStyle.Add( shapeGeom.ShapeData, shapeInstance.IfcTypeId, shapeInstance.IfcProductLabel, shapeInstance.InstanceLabel, XbimMatrix3D.Multiply(shapeInstance.Transformation, Control.WcsTransform)); break; default: throw new ArgumentOutOfRangeException(); } } } } foreach (var wpfMeshGeometry3D in styleMeshSets.Values) { wpfMeshGeometry3D.EndUpdate(); } //} if (tmpOpaquesGroup.Children.Any()) { var mv = new ModelVisual3D(); mv.Content = tmpOpaquesGroup; Control.Opaques.Children.Add(mv); Control.ModelBounds = mv.Content.Bounds.ToXbimRect3D(); } if (tmpTransparentsGroup.Children.Any()) { var mv = new ModelVisual3D(); mv.Content = tmpTransparentsGroup; Control.Transparents.Children.Add(mv); if (Control.ModelBounds.IsEmpty) Control.ModelBounds = mv.Content.Bounds.ToXbimRect3D(); else Control.ModelBounds.Union(mv.Content.Bounds.ToXbimRect3D()); } return scene; }
public XbimMeshLayer <WpfMeshGeometry3D, WpfMaterial> GetLayer(string layerKey, XbimModel model, XbimScene <WpfMeshGeometry3D, WpfMaterial> scene) { if (layerKey == "Even") { XbimColour colour = new XbimColour("Red", 1.0, 0.0, 0.0, 1); return(new XbimMeshLayer <WpfMeshGeometry3D, WpfMaterial>(model, colour) { Name = layerKey }); } else { XbimColour colour = new XbimColour("Green", 0.0, 1.0, 0.0, 1); return(new XbimMeshLayer <WpfMeshGeometry3D, WpfMaterial>(model, colour) { Name = layerKey }); } }
/// <summary> /// This version uses the new Geometry representation /// </summary> /// <param name="model"></param> /// <param name="modelTransform">The transform to place the models geometry in the right place</param> /// <param name="opaqueShapes"></param> /// <param name="transparentShapes"></param> /// <param name="exclude">List of type to exclude, by default excplict openings and spaces are excluded if exclude = null</param> /// <returns></returns> public XbimScene <WpfMeshGeometry3D, WpfMaterial> BuildScene(IModel model, XbimMatrix3D modelTransform, ModelVisual3D opaqueShapes, ModelVisual3D transparentShapes, List <Type> exclude = null) { var excludedTypes = model.DefaultExclusions(exclude); var scene = new XbimScene <WpfMeshGeometry3D, WpfMaterial>(model); var timer = new Stopwatch(); timer.Start(); using (var geomStore = model.GeometryStore) { using (var geomReader = geomStore.BeginRead()) { var materialsByStyleId = new Dictionary <int, WpfMaterial>(); var meshesByStyleId = new Dictionary <int, WpfMeshGeometry3D>(); var tmpOpaquesGroup = new Model3DGroup(); var tmpTransparentsGroup = new Model3DGroup(); //get a list of all the unique style ids then build their style and mesh var sstyleIds = geomReader.StyleIds; foreach (var styleId in sstyleIds) { var wpfMaterial = GetWpfMaterial(model, styleId); materialsByStyleId.Add(styleId, wpfMaterial); var mg = GetNewStyleMesh(wpfMaterial, tmpTransparentsGroup, tmpOpaquesGroup); meshesByStyleId.Add(styleId, mg); } var shapeInstances = GetShapeInstancesToRender(geomReader, excludedTypes); var tot = 1; if (ProgressChanged != null) { // only enumerate if there's a need for progress update tot = shapeInstances.Count(); } var prog = 0; var lastProgress = 0; // !typeof (IfcFeatureElement).IsAssignableFrom(IfcMetaData.GetType(s.IfcTypeId)) /*&& // !typeof(IfcSpace).IsAssignableFrom(IfcMetaData.GetType(s.IfcTypeId))*/); foreach (var shapeInstance in shapeInstances) { // logging var currentProgress = 100 * prog++ / tot; if (currentProgress != lastProgress && ProgressChanged != null) { ProgressChanged(this, new ProgressChangedEventArgs(currentProgress, "Creating visuals")); lastProgress = currentProgress; } // work out style var styleId = shapeInstance.StyleLabel > 0 ? shapeInstance.StyleLabel : shapeInstance.IfcTypeId * -1; if (!materialsByStyleId.ContainsKey(styleId)) { // if the style is not available we build one by ExpressType var material2 = GetWpfMaterialByType(model, shapeInstance.IfcTypeId); materialsByStyleId.Add(styleId, material2); var mg = GetNewStyleMesh(material2, tmpTransparentsGroup, tmpOpaquesGroup); meshesByStyleId.Add(styleId, mg); } var boxRep = GetSlicedBoxRepresentation(shapeInstance.BoundingBox); var targetMergeMeshByStyle = meshesByStyleId[styleId]; var transform = XbimMatrix3D.Multiply(shapeInstance.Transformation, modelTransform); targetMergeMeshByStyle.Add( boxRep, shapeInstance.IfcTypeId, shapeInstance.IfcProductLabel, shapeInstance.InstanceLabel, transform, (short)model.UserDefinedId); } foreach (var wpfMeshGeometry3D in meshesByStyleId.Values) { wpfMeshGeometry3D.EndUpdate(); } if (tmpOpaquesGroup.Children.Any()) { var mv = new ModelVisual3D { Content = tmpOpaquesGroup }; opaqueShapes.Children.Add(mv); } if (tmpTransparentsGroup.Children.Any()) { var mv = new ModelVisual3D { Content = tmpTransparentsGroup }; transparentShapes.Children.Add(mv); } } } Logger.LogDebug("Time to load visual components: {0:F3} seconds", timer.Elapsed.TotalSeconds); ProgressChanged?.Invoke(this, new ProgressChangedEventArgs(0, "Ready")); return(scene); }
public void Run() { //to start we need an ifc file, here it is Clinic_Example.ifc string ifcFile = @"IfcFiles/Clinic_Example.ifc"; string xbimFile = Path.ChangeExtension(ifcFile, "xBIM"); //will generate if not existing if (File.Exists(ifcFile)) { using (XbimModel model = new XbimModel()) { if (File.Exists(xbimFile)) { //assume the xbim file has the geometry already generated from ifc file, as below model.Open(xbimFile, XbimDBAccess.Read); } else { //create the xbim file from the ifc file model.CreateFrom(ifcFile, xbimFile, delegate(int percentProgress, object userState) { Console.Write("\rReading File {0}", percentProgress); }); model.Open(xbimFile, XbimDBAccess.ReadWrite); //readwrite as we need to add the geometry //add the the geometry information to the model int total = (int)model.Instances.CountOf <IfcProduct>(); ReportProgressDelegate progDelegate = delegate(int percentProgress, object userState) { Console.Write("\rGeometry {0} / {1}", total, (total * percentProgress / 100)); }; XbimMesher.GenerateGeometry(model, null, progDelegate); } XbimScene <XbimMeshGeometry3D, WpfMaterial> scene = GetModelScene(model); IEnumerable <IfcDoor> ifcDoors = model.IfcProducts.OfType <IfcDoor>(); //get all the ifcdoors for this model if (ifcDoors.Any()) { IfcDoor ifcDoor = ifcDoors.First(); //we use the first door int entLbl = Math.Abs(ifcDoor.EntityLabel); foreach (var layer in scene.Layers) //loop material layers { var hidden = layer.Hidden as XbimMeshGeometry3D; //stored the points in Hidden if (hidden != null) { foreach (var m in hidden.Meshes) //display simple count information { if (m.EntityLabel != entLbl) { continue; //skip doors that do not match label } int startIndex = m.StartPosition; int endIndex = m.EndPosition; int startTriIndex = m.StartTriangleIndex; int endTriIndex = m.EndTriangleIndex; List <XbimPoint3D> vertex = hidden.Positions.GetRange(startIndex, (endIndex - startIndex) + 1); List <XbimVector3D> normals = hidden.Normals.GetRange(startIndex, (endIndex - startIndex) + 1); List <int> triangleIndexs = hidden.TriangleIndices.GetRange(startIndex, (endTriIndex - startTriIndex) + 1); Console.WriteLine("\n-------------Geometry Triangle Information-------------"); Console.WriteLine("Entity Type = IfcDoor"); Console.WriteLine("Entity Label = {0}", entLbl); Console.WriteLine("Layer = {0}", layer.Name); Console.WriteLine("Vertex count = {0}", vertex.Count); Console.WriteLine("Normal count = {0}", normals.Count); Console.WriteLine("TriangleIndexs count = {0}", triangleIndexs.Count); Console.WriteLine("---------------------------------------------------------"); } } } } } } }
XbimScene <WpfMeshGeometry3D, WpfMaterial> ILayerStyler.BuildScene(IModel model, XbimMatrix3D modelTransform, ModelVisual3D opaqueShapes, ModelVisual3D transparentShapes, List <Type> exclude) { var excludedTypes = model.DefaultExclusions(exclude); var tmpOpaquesGroup = new Model3DGroup(); var retScene = new XbimScene <WpfMeshGeometry3D, WpfMaterial>(model); var meshes = new List <WpfMeshGeometry3D>(); if (_discriminator == null) { _discriminator = new VisualDiscriminator(_window.Doc); } if (_model.Instances == null || !_model.Instances.Any()) { return(retScene); } var red = PrepareMesh(_colourFail); meshes.Add(red); var green = PrepareMesh(_colourPass); meshes.Add(green); var blue = PrepareMesh(_colourNa); meshes.Add(blue); var amber = PrepareMesh(_colourWarning); meshes.Add(amber); foreach (var mesh in meshes) { mesh.WpfModel.SetValue(FrameworkElement.TagProperty, mesh); mesh.BeginUpdate(); tmpOpaquesGroup.Children.Add(mesh); } using (var geomStore = model.GeometryStore) { using (var geomReader = geomStore.BeginRead()) { var shapeInstances = geomReader.ShapeInstances .Where(s => s.RepresentationType == XbimGeometryRepresentationType.OpeningsAndAdditionsIncluded && !excludedTypes.Contains(s.IfcTypeId)); foreach (var shapeInstance in shapeInstances) { var ent = _model.Instances[shapeInstance.IfcProductLabel]; var grp = _discriminator.GetLayerGroup(ent); if (grp == VisualDiscriminator.LayerGroup.Null) { continue; } if (!UseBlue && grp == VisualDiscriminator.LayerGroup.Blue) { continue; } if (!UseAmber && grp == VisualDiscriminator.LayerGroup.Amber) { continue; } WpfMeshGeometry3D targetMergeMesh = null; switch (grp) { case VisualDiscriminator.LayerGroup.Red: targetMergeMesh = red; break; case VisualDiscriminator.LayerGroup.Green: targetMergeMesh = green; break; case VisualDiscriminator.LayerGroup.Blue: targetMergeMesh = blue; break; case VisualDiscriminator.LayerGroup.Amber: targetMergeMesh = amber; break; } if (targetMergeMesh == null) { continue; } IXbimShapeGeometryData shapeGeom = geomReader.ShapeGeometry(shapeInstance.ShapeGeometryLabel); if (shapeGeom.Format == (byte)XbimGeometryType.PolyhedronBinary) { var transform = XbimMatrix3D.Multiply(shapeInstance.Transformation, modelTransform); targetMergeMesh.Add( shapeGeom.ShapeData, shapeInstance.IfcTypeId, shapeInstance.IfcProductLabel, shapeInstance.InstanceLabel, transform, (short)model.UserDefinedId); } } } } foreach (var mesh in meshes) { mesh.EndUpdate(); } if (!tmpOpaquesGroup.Children.Any()) { return(retScene); } var mv = new ModelVisual3D { Content = tmpOpaquesGroup }; opaqueShapes.Children.Add(mv); // no transparents are present //if (tmpTransparentsGroup.Children.Any()) //{ // var mv = new ModelVisual3D { Content = tmpTransparentsGroup }; // transparentShapes.Children.Add(mv); //} return(retScene); }
/// <summary> /// This version uses the new Geometry representation /// </summary> /// <param name="model"></param> /// <param name="modelTransform">The transform to place the models geometry in the right place</param> /// <param name="opaqueShapes"></param> /// <param name="transparentShapes"></param> /// <param name="isolateInstances">List of instances to be isolated</param> /// <param name="hideInstances">List of instances to be hidden</param> /// <param name="excludeTypes">List of type to exclude, by default excplict openings and spaces are excluded if exclude = null</param> /// <returns></returns> public XbimScene <WpfMeshGeometry3D, WpfMaterial> BuildScene(IModel model, XbimMatrix3D modelTransform, ModelVisual3D opaqueShapes, ModelVisual3D transparentShapes, List <IPersistEntity> isolateInstances = null, List <IPersistEntity> hideInstances = null, List <Type> excludeTypes = null) { var excludedTypes = model.DefaultExclusions(excludeTypes); var onlyInstances = isolateInstances?.Where(i => i.Model == model).ToDictionary(i => i.EntityLabel); var hiddenInstances = hideInstances?.Where(i => i.Model == model).ToDictionary(i => i.EntityLabel); var scene = new XbimScene <WpfMeshGeometry3D, WpfMaterial>(model); var timer = new Stopwatch(); timer.Start(); using (var geomStore = model.GeometryStore) { using (var geomReader = geomStore.BeginRead()) { // we are keeping the style to decide if a new element needs to be transparent. // var materialsByStyleId = new Dictionary <int, WpfMaterial>(); var repeatedShapeGeometries = new Dictionary <int, MeshGeometry3D>(); var tmpOpaquesGroup = new Model3DGroup(); var tmpTransparentsGroup = new Model3DGroup(); //get a list of all the unique style ids then build their style and mesh // var sstyleIds = geomReader.StyleIds; foreach (var styleId in sstyleIds) { var wpfMaterial = GetWpfMaterial(model, styleId); materialsByStyleId.Add(styleId, wpfMaterial); } var shapeInstances = GetShapeInstancesToRender(geomReader, excludedTypes); var tot = 1; if (ProgressChanged != null) { // only enumerate if there's a need for progress update tot = shapeInstances.Count(); } var prog = 0; var lastProgress = 0; // !typeof (IfcFeatureElement).IsAssignableFrom(IfcMetaData.GetType(s.IfcTypeId)) /*&& // !typeof(IfcSpace).IsAssignableFrom(IfcMetaData.GetType(s.IfcTypeId))*/); // foreach (var shapeInstance in shapeInstances .Where(s => null == onlyInstances || onlyInstances.Count == 0 || onlyInstances.Keys.Contains(s.IfcProductLabel)) .Where(s => null == hiddenInstances || hiddenInstances.Count == 0 || !hiddenInstances.Keys.Contains(s.IfcProductLabel))) { int id = shapeInstance.IfcProductLabel; //LINKS TO ACTUAL ELEMENT ShadedElement el = elements[id]; var i = model.Instances[id]; // logging var currentProgress = 100 * prog++ / tot; if (currentProgress != lastProgress && ProgressChanged != null) { ProgressChanged(this, new ProgressChangedEventArgs(currentProgress, "Creating visuals")); lastProgress = currentProgress; } // work out style var styleId = shapeInstance.StyleLabel > 0 ? shapeInstance.StyleLabel : shapeInstance.IfcTypeId * -1; WpfMaterial selectedMaterial; if (!materialsByStyleId.TryGetValue(styleId, out selectedMaterial)) { // if the style is not available we build one by ExpressType selectedMaterial = GetWpfMaterialByType(model, shapeInstance.IfcTypeId); materialsByStyleId.Add(styleId, selectedMaterial); } int colorIndex = (int)el.currCriticality; selectedMaterial = new WpfMaterial(colsPerCriticality[colorIndex]); //GET THE ACTUAL GEOMETRY MeshGeometry3D wpfMesh; //see if we have already read it if (!repeatedShapeGeometries.TryGetValue(shapeInstance.ShapeGeometryLabel, out wpfMesh)) { IXbimShapeGeometryData shapeGeom = geomReader.ShapeGeometry(shapeInstance.ShapeGeometryLabel); if ((XbimGeometryType)shapeGeom.Format != XbimGeometryType.PolyhedronBinary) { continue; } wpfMesh = new MeshGeometry3D(); wpfMesh.Read(shapeGeom.ShapeData); if (shapeGeom.ReferenceCount > 1) //only store if we are going to use again { repeatedShapeGeometries.Add(shapeInstance.ShapeGeometryLabel, wpfMesh); } } var mg = new GeometryModel3D(wpfMesh, selectedMaterial); mg.BackMaterial = mg.Material; mg.SetValue(FrameworkElement.TagProperty, new XbimInstanceHandle(model, shapeInstance.IfcProductLabel, shapeInstance.IfcTypeId)); mg.Transform = XbimMatrix3D.Multiply(shapeInstance.Transformation, modelTransform).ToMatrixTransform3D(); if (materialsByStyleId[styleId].IsTransparent) { tmpTransparentsGroup.Children.Add(mg); } else { tmpOpaquesGroup.Children.Add(mg); } } if (tmpOpaquesGroup.Children.Any()) { var mv = new ModelVisual3D { Content = tmpOpaquesGroup }; opaqueShapes.Children.Add(mv); } if (tmpTransparentsGroup.Children.Any()) { var mv = new ModelVisual3D { Content = tmpTransparentsGroup }; transparentShapes.Children.Add(mv); } } } Logger.LogDebug("Time to load visual components: {0:F3} seconds", timer.Elapsed.TotalSeconds); ProgressChanged?.Invoke(this, new ProgressChangedEventArgs(0, "Ready")); return(scene); }
/// <summary> /// Generate a Scene /// </summary> /// <param name="model"></param> /// <returns></returns> public XbimScene<XbimMeshGeometry3D, WpfMaterial> GetModelScene(XbimModel model) { //we need a class which implements IXbimRenderMaterial for the material, you might also want to implement a class for Material depending on your needs, //using the WpfMaterial class that then used the Media3D material class as implemented by the XBimXplorer for convenience. XbimScene<XbimMeshGeometry3D, WpfMaterial> scene = new XbimScene<XbimMeshGeometry3D, WpfMaterial>(model); XbimGeometryHandleCollection handles = new XbimGeometryHandleCollection(model.GetGeometryHandles() .Exclude(IfcEntityNameEnum.IFCFEATUREELEMENT)); foreach (var layerContent in handles.GroupByBuildingElementTypes()) { string elementTypeName = layerContent.Key; XbimGeometryHandleCollection layerHandles = layerContent.Value; IEnumerable<XbimGeometryData> geomColl = model.GetGeometryData(layerHandles); XbimColour colour = scene.LayerColourMap[elementTypeName]; XbimMeshLayer<XbimMeshGeometry3D, WpfMaterial> layer = new XbimMeshLayer<XbimMeshGeometry3D, WpfMaterial>(model, colour) { Name = elementTypeName }; //add all content initially into the hidden field foreach (var geomData in geomColl) { layer.AddToHidden(geomData, model); } scene.Add(layer); } return scene; }
/// <summary> /// This version uses the new Geometry representation /// </summary> /// <param name="model"></param> /// <param name="modelTransform">The transform to place the models geometry in the right place</param> /// <param name="opaqueShapes"></param> /// <param name="transparentShapes"></param> /// <param name="exclude">List of type to exclude, by default excplict openings and spaces are excluded if exclude = null</param> /// <returns></returns> public XbimScene <WpfMeshGeometry3D, WpfMaterial> BuildScene(IModel model, XbimMatrix3D modelTransform, ModelVisual3D opaqueShapes, ModelVisual3D transparentShapes, List <Type> exclude = null) { var excludedTypes = model.DefaultExclusions(exclude); var scene = new XbimScene <WpfMeshGeometry3D, WpfMaterial>(model); var timer = new Stopwatch(); timer.Start(); using (var geomStore = model.GeometryStore) { using (var geomReader = geomStore.BeginRead()) { var materialsByStyleId = new Dictionary <int, WpfMaterial>(); var repeatedShapeGeometries = new Dictionary <int, MeshGeometry3D>(); var meshesByStyleId = new Dictionary <int, WpfMeshGeometry3D>(); var tmpOpaquesGroup = new Model3DGroup(); var tmpTransparentsGroup = new Model3DGroup(); //get a list of all the unique style ids then build their style and mesh var sstyleIds = geomReader.StyleIds; foreach (var styleId in sstyleIds) { var wpfMaterial = GetWpfMaterial(model, styleId); materialsByStyleId.Add(styleId, wpfMaterial); var mg = GetNewStyleMesh(wpfMaterial, tmpTransparentsGroup, tmpOpaquesGroup); meshesByStyleId.Add(styleId, mg); } var shapeInstances = GetShapeInstancesToRender(geomReader, excludedTypes); var tot = 1; if (ProgressChanged != null) { // only enumerate if there's a need for progress update tot = shapeInstances.Count(); } var prog = 0; var lastProgress = 0; // !typeof (IfcFeatureElement).IsAssignableFrom(IfcMetaData.GetType(s.IfcTypeId)) /*&& // !typeof(IfcSpace).IsAssignableFrom(IfcMetaData.GetType(s.IfcTypeId))*/); foreach (var shapeInstance in shapeInstances) { // logging var currentProgress = 100 * prog++ / tot; if (currentProgress != lastProgress && ProgressChanged != null) { ProgressChanged(this, new ProgressChangedEventArgs(currentProgress, "Creating visuals")); lastProgress = currentProgress; } // work out style var styleId = shapeInstance.StyleLabel > 0 ? shapeInstance.StyleLabel : shapeInstance.IfcTypeId * -1; if (!materialsByStyleId.ContainsKey(styleId)) { // if the style is not available we build one by ExpressType var material2 = GetWpfMaterialByType(model, shapeInstance.IfcTypeId); materialsByStyleId.Add(styleId, material2); var mg = GetNewStyleMesh(material2, tmpTransparentsGroup, tmpOpaquesGroup); meshesByStyleId.Add(styleId, mg); } //GET THE ACTUAL GEOMETRY MeshGeometry3D wpfMesh; //see if we have already read it if (UseMaps && repeatedShapeGeometries.TryGetValue(shapeInstance.ShapeGeometryLabel, out wpfMesh)) { var mg = new GeometryModel3D(wpfMesh, materialsByStyleId[styleId]); mg.SetValue(FrameworkElement.TagProperty, new XbimInstanceHandle(model, shapeInstance.IfcProductLabel, shapeInstance.IfcTypeId)); mg.BackMaterial = mg.Material; mg.Transform = XbimMatrix3D.Multiply(shapeInstance.Transformation, modelTransform) .ToMatrixTransform3D(); if (materialsByStyleId[styleId].IsTransparent) { tmpTransparentsGroup.Children.Add(mg); } else { tmpOpaquesGroup.Children.Add(mg); } } else //we need to get the shape geometry { IXbimShapeGeometryData shapeGeom = geomReader.ShapeGeometry(shapeInstance.ShapeGeometryLabel); if (UseMaps && shapeGeom.ReferenceCount > 1) //only store if we are going to use again { wpfMesh = new MeshGeometry3D(); switch ((XbimGeometryType)shapeGeom.Format) { case XbimGeometryType.PolyhedronBinary: wpfMesh.Read(shapeGeom.ShapeData); break; case XbimGeometryType.Polyhedron: wpfMesh.Read(((XbimShapeGeometry)shapeGeom).ShapeData); break; } repeatedShapeGeometries.Add(shapeInstance.ShapeGeometryLabel, wpfMesh); var mg = new GeometryModel3D(wpfMesh, materialsByStyleId[styleId]); mg.SetValue(FrameworkElement.TagProperty, new XbimInstanceHandle(model, shapeInstance.IfcProductLabel, shapeInstance.IfcTypeId)); mg.BackMaterial = mg.Material; mg.Transform = XbimMatrix3D.Multiply(shapeInstance.Transformation, modelTransform).ToMatrixTransform3D(); if (materialsByStyleId[styleId].IsTransparent) { tmpTransparentsGroup.Children.Add(mg); } else { tmpOpaquesGroup.Children.Add(mg); } } else //it is a one off, merge it with shapes of same style { var targetMergeMeshByStyle = meshesByStyleId[styleId]; // replace target mesh beyond suggested size // https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/maximize-wpf-3d-performance // if (targetMergeMeshByStyle.PositionCount > 20000 || targetMergeMeshByStyle.TriangleIndexCount > 60000 ) { targetMergeMeshByStyle.EndUpdate(); var replace = GetNewStyleMesh(materialsByStyleId[styleId], tmpTransparentsGroup, tmpOpaquesGroup); meshesByStyleId[styleId] = replace; targetMergeMeshByStyle = replace; } // end replace if (shapeGeom.Format != (byte)XbimGeometryType.PolyhedronBinary) { continue; } var transform = XbimMatrix3D.Multiply(shapeInstance.Transformation, modelTransform); targetMergeMeshByStyle.Add( shapeGeom.ShapeData, shapeInstance.IfcTypeId, shapeInstance.IfcProductLabel, shapeInstance.InstanceLabel, transform, (short)model.UserDefinedId); } } } foreach (var wpfMeshGeometry3D in meshesByStyleId.Values) { wpfMeshGeometry3D.EndUpdate(); } if (tmpOpaquesGroup.Children.Any()) { var mv = new ModelVisual3D { Content = tmpOpaquesGroup }; opaqueShapes.Children.Add(mv); } if (tmpTransparentsGroup.Children.Any()) { var mv = new ModelVisual3D { Content = tmpTransparentsGroup }; transparentShapes.Children.Add(mv); } } } Log.DebugFormat("Time to load visual components: {0:F3} seconds", timer.Elapsed.TotalSeconds); ProgressChanged?.Invoke(this, new ProgressChangedEventArgs(0, "Ready")); return(scene); }
XbimScene <WpfMeshGeometry3D, WpfMaterial> ILayerStyler.BuildScene(IModel model, XbimMatrix3D modelTransform, ModelVisual3D opaqueShapes, ModelVisual3D transparentShapes, List <Type> exclude) { var excludedTypes = model.DefaultExclusions(exclude); var tmpOpaquesGroup = new Model3DGroup(); var retScene = new XbimScene <WpfMeshGeometry3D, WpfMaterial>(model); if (_model.Instances == null || !_model.Instances.Any()) { return(retScene); } // define colours var colours = new Dictionary <LayerGroup, XbimColour>(); colours.Add(LayerGroup.Green, new XbimColour("Green", 0.0, 1.0, 0.0, 0.5)); colours.Add(LayerGroup.Red, new XbimColour("Red", 1.0, 0.0, 0.0, 0.5)); colours.Add(LayerGroup.Amber, new XbimColour("Amber", .5, 0.5, .5, .8)); // actually grey // prepare meshes // var meshes = new List <WpfMeshGeometry3D>(); // this list gets added to the scene at the end. // this dictionary holds the list of meshes that are currently used, as they are filled (in size), // new ones get replaced // var meshDic = new Dictionary <LayerGroup, WpfMeshGeometry3D>(); foreach (var group in colours.Keys) { var newItem = PrepareMesh(colours[group]); meshDic.Add(group, newItem); meshes.Add(newItem); } foreach (var mesh in meshes) { mesh.WpfModel.SetValue(FrameworkElement.TagProperty, mesh); mesh.BeginUpdate(); tmpOpaquesGroup.Children.Add(mesh); } using (var geomStore = model.GeometryStore) { using (var geomReader = geomStore.BeginRead()) { var shapeInstances = geomReader.ShapeInstances .Where(s => s.RepresentationType == XbimGeometryRepresentationType.OpeningsAndAdditionsIncluded && !excludedTypes.Contains(s.IfcTypeId)); foreach (var shapeInstance in shapeInstances) { var ent = _model.Instances[shapeInstance.IfcProductLabel]; var grp = GetLayerGroup(ent); if (grp == LayerGroup.Null) { continue; } if (!UseAmber && grp == LayerGroup.Amber) { continue; } WpfMeshGeometry3D targetMergeMesh; meshDic.TryGetValue(grp, out targetMergeMesh); if (targetMergeMesh == null) { continue; } // replace target mesh beyond suggested size // https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/maximize-wpf-3d-performance // if (targetMergeMesh.PositionCount > 20000 || targetMergeMesh.TriangleIndexCount > 60000 ) { // end current mesh targetMergeMesh.EndUpdate(); // prepare new one and add to the list var replace = PrepareMesh(colours[grp]); meshes.Add(replace); // swap mesh in dicionary and for this loop meshDic[grp] = replace; targetMergeMesh = replace; // prepare in output replace.WpfModel.SetValue(FrameworkElement.TagProperty, replace); replace.BeginUpdate(); tmpOpaquesGroup.Children.Add(replace); } IXbimShapeGeometryData shapeGeom = geomReader.ShapeGeometry(shapeInstance.ShapeGeometryLabel); if (shapeGeom.Format == (byte)XbimGeometryType.PolyhedronBinary) { var transform = XbimMatrix3D.Multiply(shapeInstance.Transformation, modelTransform); targetMergeMesh.Add( shapeGeom.ShapeData, shapeInstance.IfcTypeId, shapeInstance.IfcProductLabel, shapeInstance.InstanceLabel, transform, (short)model.UserDefinedId); } } } } foreach (var mesh in meshDic.Values) { mesh.EndUpdate(); } if (!tmpOpaquesGroup.Children.Any()) { return(retScene); } var mv = new ModelVisual3D { Content = tmpOpaquesGroup }; opaqueShapes.Children.Add(mv); return(retScene); }
public XbimScene<WpfMeshGeometry3D, WpfMaterial> BuildScene(XbimModel model, Xbim3DModelContext context, List<Type> exclude = null) { var tmpOpaquesGroup = new Model3DGroup(); var retScene = new XbimScene<WpfMeshGeometry3D, WpfMaterial>(model); var red = PrepareMesh(new XbimColour("Red", 1.0, 0.0, 0.0)); var green = PrepareMesh(new XbimColour("Green", 0.0, 1.0, 0.0)); var amber =PrepareMesh(new XbimColour("Amber", 0.0, 0.0, 1.0, 0.9)); tmpOpaquesGroup.Children.Add(red); tmpOpaquesGroup.Children.Add(green); tmpOpaquesGroup.Children.Add(amber); var i = 0; 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))*/)) { IXbimShapeGeometryData shapeGeom = context.ShapeGeometry(shapeInstance.ShapeGeometryLabel); WpfMeshGeometry3D targetMergeMesh; switch (i++%3) { case 0: targetMergeMesh = red; break; case 1: targetMergeMesh = green; break; default: targetMergeMesh = amber; break; } switch ((XbimGeometryType)shapeGeom.Format) { case XbimGeometryType.Polyhedron: var shapePoly = (XbimShapeGeometry)shapeGeom; targetMergeMesh.Add( shapePoly.ShapeData, shapeInstance.IfcTypeId, shapeInstance.IfcProductLabel, shapeInstance.InstanceLabel, XbimMatrix3D.Multiply(shapeInstance.Transformation, Control.ModelPositions[model].Transfrom), model.UserDefinedId ); break; case XbimGeometryType.PolyhedronBinary: targetMergeMesh.Add( shapeGeom.ShapeData, shapeInstance.IfcTypeId, shapeInstance.IfcProductLabel, shapeInstance.InstanceLabel, XbimMatrix3D.Multiply(shapeInstance.Transformation, Control.ModelPositions[model].Transfrom), model.UserDefinedId); break; default: throw new ArgumentOutOfRangeException(); } } var mv = new ModelVisual3D {Content = tmpOpaquesGroup}; Control.OpaquesVisual3D.Children.Add(mv); Control.ModelBounds = mv.Content.Bounds.ToXbimRect3D(); return retScene; }
/// <summary> /// This version uses the new Geometry representation /// </summary> /// <param name="model"></param> /// <param name="modelTransform">The transform to place the models geometry in the right place</param> /// <param name="opaqueShapes"></param> /// <param name="transparentShapes"></param> /// <param name="exclude">List of type to exclude, by default excplict openings and spaces are excluded if exclude = null</param> /// <returns></returns> public XbimScene <WpfMeshGeometry3D, WpfMaterial> BuildScene(IModel model, XbimMatrix3D modelTransform, ModelVisual3D opaqueShapes, ModelVisual3D transparentShapes, List <Type> exclude = null) { var excludedTypes = model.DefaultExclusions(exclude); var scene = new XbimScene <WpfMeshGeometry3D, WpfMaterial>(model); var timer = new Stopwatch(); timer.Start(); using (var geomStore = model.GeometryStore) { using (var geomReader = geomStore.BeginRead()) { var materialsByStyleId = new Dictionary <int, WpfMaterial>(); var repeatedShapeGeometries = new Dictionary <int, MeshGeometry3D>(); var meshesByStyleId = new Dictionary <int, WpfMeshGeometry3D>(); var tmpOpaquesGroup = new Model3DGroup(); var tmpTransparentsGroup = new Model3DGroup(); //get a list of all the unique style ids then build their style and mesh var sstyleIds = geomReader.StyleIds; foreach (var styleId in sstyleIds) { var wpfMaterial = GetWpfMaterial(model, styleId); materialsByStyleId.Add(styleId, wpfMaterial); var mg = GetNewStyleMesh(wpfMaterial, tmpTransparentsGroup, tmpOpaquesGroup); meshesByStyleId.Add(styleId, mg); } var shapeInstances = geomReader.ShapeInstances .Where(s => s.RepresentationType == XbimGeometryRepresentationType.OpeningsAndAdditionsIncluded && !excludedTypes.Contains(s.IfcTypeId)); var tot = shapeInstances.Count(); var prog = 0; var lastProgress = 0; // !typeof (IfcFeatureElement).IsAssignableFrom(IfcMetaData.GetType(s.IfcTypeId)) /*&& // !typeof(IfcSpace).IsAssignableFrom(IfcMetaData.GetType(s.IfcTypeId))*/); foreach (var shapeInstance in shapeInstances) { // logging var currentProgress = 100 * prog++ / tot; if (currentProgress != lastProgress && ProgressChanged != null) { ProgressChanged(this, new ProgressChangedEventArgs(currentProgress, "Creating visuals")); lastProgress = currentProgress; // Log.DebugFormat("Progress to {0}% time: {1} seconds", lastProgress, timer.Elapsed.TotalSeconds.ToString("F3")); // Debug.Print("Progress to {0}% time:\t{1} seconds", lastProgress, timer.Elapsed.TotalSeconds.ToString("F3")); } // work out style var styleId = shapeInstance.StyleLabel > 0 ? shapeInstance.StyleLabel : shapeInstance.IfcTypeId * -1; if (!materialsByStyleId.ContainsKey(styleId)) { // if the style is not available we build one by ExpressType var material2 = GetWpfMaterialByType(model, shapeInstance.IfcTypeId); materialsByStyleId.Add(styleId, material2); var mg = GetNewStyleMesh(material2, tmpTransparentsGroup, tmpOpaquesGroup); meshesByStyleId.Add(styleId, mg); } //GET THE ACTUAL GEOMETRY MeshGeometry3D wpfMesh; //see if we have already read it if (UseMaps && repeatedShapeGeometries.TryGetValue(shapeInstance.ShapeGeometryLabel, out wpfMesh)) { var mg = new GeometryModel3D(wpfMesh, materialsByStyleId[styleId]); mg.SetValue(FrameworkElement.TagProperty, new XbimInstanceHandle(model, shapeInstance.IfcProductLabel, shapeInstance.IfcTypeId)); mg.BackMaterial = mg.Material; mg.Transform = XbimMatrix3D.Multiply(shapeInstance.Transformation, modelTransform) .ToMatrixTransform3D(); if (materialsByStyleId[styleId].IsTransparent) { tmpTransparentsGroup.Children.Add(mg); } else { tmpOpaquesGroup.Children.Add(mg); } } else //we need to get the shape geometry { IXbimShapeGeometryData shapeGeom = geomReader.ShapeGeometry(shapeInstance.ShapeGeometryLabel); if (UseMaps && shapeGeom.ReferenceCount > 1) //only store if we are going to use again { wpfMesh = new MeshGeometry3D(); switch ((XbimGeometryType)shapeGeom.Format) { case XbimGeometryType.PolyhedronBinary: wpfMesh.Read(shapeGeom.ShapeData); break; case XbimGeometryType.Polyhedron: wpfMesh.Read(((XbimShapeGeometry)shapeGeom).ShapeData); break; } repeatedShapeGeometries.Add(shapeInstance.ShapeGeometryLabel, wpfMesh); var mg = new GeometryModel3D(wpfMesh, materialsByStyleId[styleId]); mg.SetValue(FrameworkElement.TagProperty, new XbimInstanceHandle(model, shapeInstance.IfcProductLabel, shapeInstance.IfcTypeId)); mg.BackMaterial = mg.Material; mg.Transform = XbimMatrix3D.Multiply(shapeInstance.Transformation, modelTransform).ToMatrixTransform3D(); if (materialsByStyleId[styleId].IsTransparent) { tmpTransparentsGroup.Children.Add(mg); } else { tmpOpaquesGroup.Children.Add(mg); } } else //it is a one off, merge it with shapes of same style { var targetMergeMeshByStyle = meshesByStyleId[styleId]; if (shapeGeom.Format != (byte)XbimGeometryType.PolyhedronBinary) { continue; } var transform = XbimMatrix3D.Multiply(shapeInstance.Transformation, modelTransform); targetMergeMeshByStyle.Add( shapeGeom.ShapeData, shapeInstance.IfcTypeId, shapeInstance.IfcProductLabel, shapeInstance.InstanceLabel, transform, (short)model.UserDefinedId); } } } foreach (var wpfMeshGeometry3D in meshesByStyleId.Values) { wpfMeshGeometry3D.EndUpdate(); } //} if (tmpOpaquesGroup.Children.Any()) { var mv = new ModelVisual3D { Content = tmpOpaquesGroup }; opaqueShapes.Children.Add(mv); // Control.ModelBounds = mv.Content.Bounds.ToXbimRect3D(); } if (tmpTransparentsGroup.Children.Any()) { var mv = new ModelVisual3D { Content = tmpTransparentsGroup }; transparentShapes.Children.Add(mv); //if (Control.ModelBounds.IsEmpty) Control.ModelBounds = mv.Content.Bounds.ToXbimRect3D(); //else Control.ModelBounds.Union(mv.Content.Bounds.ToXbimRect3D()); } } } Log.DebugFormat("Time to load visual components: {0} seconds", timer.Elapsed.TotalSeconds.ToString("F3")); if (ProgressChanged != null) { ProgressChanged(this, new ProgressChangedEventArgs(0, "Ready")); } return(scene); }