private GeometryModel3D Box(double width, double length, double height) { var model = new GeometryModel3D(); model.SetValue(FrameworkElement.NameProperty, "box"); var mb = new MeshBuilder(); mb.AddBox(new Point3D(0, 0, height*0.5), width, length, height); model.Geometry = mb.ToMesh(); model.Material = material; return model; }
/// <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; }