示例#1
0
 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;
        }