示例#1
0
        /// <summary>
        /// 获取一个ifcproduct的boundingbox
        /// </summary>
        /// <param name="product">指定的product</param>
        /// <returns>XbimRect3D精度为2位的盒子</returns>
        public XbimRect3D GetAABB(IIfcProduct product)
        {
            //Xbim3DModelContext context = new Xbim3DModelContext(model);
            //context.CreateContext();
            XbimRect3D prodBox = XbimRect3D.Empty;

            if (context.ShapeInstancesOf(product).Count() == 0)
            {
                return(prodBox);
            }

            foreach (var shp in context.ShapeInstancesOf(product))
            {
                var bb = shp.BoundingBox;
                bb = XbimRect3D.TransformBy(bb, shp.Transformation);
                if (prodBox.IsEmpty)
                {
                    prodBox = bb;
                }
                else
                {
                    prodBox.Union(bb);
                }
            }

            //精度为2位小数
            prodBox.Round(2);
            return(prodBox);
            //Console.WriteLine(prodBox.ToString());
        }
示例#2
0
        /// <summary>
        /// Constructor of spatial relations analyser of axis aligned bounding boxes of the products.
        /// If you already have a dictionary of the AABBoxes and products you should use the other constructor
        /// </summary>
        /// <param name="model">Building model</param>
        public XbimAABBoxAnalyser(XbimModel model)
        {
            _model = model;
            Xbim3DModelContext context = new Xbim3DModelContext(model);

            if (model.GeometriesCount == 0)
            {
                context.CreateContext();
            }


            //create cached BBoxes
            foreach (var prod in model.IfcProducts.Cast <IfcProduct>())
            {
                XbimRect3D prodBox = XbimRect3D.Empty;
                foreach (var shp in context.ShapeInstancesOf(prod))
                {
                    //bounding boxes are lightweight and are produced when geometry is created at first place

                    //get or cast to BBox
                    var bb = shp.BoundingBox;
                    bb = XbimRect3D.TransformBy(bb, shp.Transformation);
                    if (prodBox.IsEmpty)
                    {
                        prodBox = bb;
                    }
                    else
                    {
                        prodBox.Union(bb);
                    }
                    //add every BBox to the world to get the size and position of the world
                }
                _prodBBs.Add(prod, prodBox);
            }
        }
示例#3
0
        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
            }
        }