示例#1
0
        /// <summary>
        /// Adds the geometry fragment to the hidden mesh, if the model is not null
        /// the fragment is placed on a sub layer of the correct style
        /// the sub layer is automaticaly created if it does not exist.
        /// </summary>
        /// <param name="geomData"></param>
        /// <param name="model"></param>
        public void AddToHidden(XbimGeometryData geomData, IModel model, short modelId)
        {
            var addingSuccessfull = Hidden.Add(geomData, modelId); // this is where the geometry is added to the main layer.

            if (addingSuccessfull)
            {
                return;
            }
            //if the main layer is too big split it.
            //try and find a sublayer that is a split of this, i.e. has the same texture
            foreach (var sublayer in _subLayerMap.Reverse())
            {
                if (!Equals(sublayer.Style, Style))
                {
                    continue;
                }
                sublayer.AddToHidden(geomData, model, modelId); //try and add the data to this mesh
                return;                                         //succeeded so return
            }
            //didn't find a layer to add it to so create a new one
            var subLayer = new XbimMeshLayer <TMesh, TMaterial>(model, Style)
            {
                Name = Name + "-" + _subLayerMap.Count
            };

            _subLayerMap.Add(subLayer);
            subLayer.Hidden.Add(geomData, modelId); //this should always pass as it is a new mesh and ifc geom rarely exceeds max mesh size, graphics cards will truncate anyway
        }
示例#2
0
        /// <summary>
        /// Adds the geometry fragment to the hidden mesh, if the model is not null
        /// the fragment is placed on a sub layer of the correct style
        /// the sub layer is automaticaly created if it does not exist.
        /// </summary>
        /// <param name="geomData"></param>
        /// <param name="model"></param>
        public void AddToHidden(XbimGeometryData geomData, IModel model = null)
        {
            int modelId = 0;

            if (model != null)
            {
                modelId = model.UserDefinedId;
            }
            if (model != null && geomData.StyleLabel > 0) // check if we need to put this item on a sub layer
            {
                XbimMeshLayer <TMesh, TMaterial> subLayer;
                var layerName = geomData.StyleLabel.ToString();
                if (!_subLayerMap.Contains(layerName))
                {
                    var style = model.Instances[geomData.StyleLabel] as IfcSurfaceStyle;
                    //create a sub layer
                    subLayer = new XbimMeshLayer <TMesh, TMaterial>(model, style)
                    {
                        Name = layerName
                    };
                    _subLayerMap.Add(subLayer);
                }
                else
                {
                    subLayer = _subLayerMap[layerName];
                }

                subLayer.AddToHidden(geomData, null, (short)modelId);
            }
            else
            {
                AddToHidden(geomData, model, (short)modelId);
            }
        }
示例#3
0
        /// <summary>
        /// Appends a geometry data object to the Mesh, returns false if the mesh would become too big and needs splitting
        /// </summary>
        /// <param name="geometryMeshData"></param>
        public bool Add(XbimGeometryData geometryMeshData, short modelId = 0)
        {
            var transform = XbimMatrix3D.FromArray(geometryMeshData.DataArray2);

            if (geometryMeshData.GeometryType == XbimGeometryType.TriangulatedMesh)
            {
                var strm     = new XbimTriangulatedModelStream(geometryMeshData.ShapeData);
                var fragment = strm.BuildWithNormals(this, transform, modelId);
                if (fragment.EntityLabel == -1) //nothing was added due to size being exceeded
                {
                    return(false);
                }
                fragment.EntityLabel  = geometryMeshData.IfcProductLabel;
                fragment.EntityTypeId = geometryMeshData.IfcTypeId;
                _meshes.Add(fragment);
            }
            else if (geometryMeshData.GeometryType == XbimGeometryType.BoundingBox)
            {
                var r3D = XbimRect3D.FromArray(geometryMeshData.ShapeData);
                Add(MakeBoundingBox(r3D, transform), geometryMeshData.IfcProductLabel, IfcMetaData.GetType(geometryMeshData.IfcTypeId), modelId);
            }
            else
            {
                throw new XbimException("Illegal geometry type found");
            }
            return(true);
        }
示例#4
0
        public static string GeomInfoBoundBox(XbimModel model, int iEntLabel)
        {
            XbimGeometryData geomdata = model.GetGeometryData(iEntLabel, XbimGeometryType.BoundingBox).FirstOrDefault();

            if (geomdata == null)
            {
                return("<not found>");
            }

            XbimRect3D r3d = XbimRect3D.FromArray(geomdata.ShapeData);

            return(string.Format("Bounding box (position, size): {0}", r3d.ToString()));
        }
示例#5
0
 /// <summary>
 /// Do not use this rather create a XbimMeshGeometry3D first and construct this from it, appending WPF collections is slow
 /// </summary>
 /// <param name="geometryMeshData"></param>
 /// <param name="modelId"></param>
 public bool Add(XbimGeometryData geometryMeshData, short modelId)
 {
     throw new NotImplementedException();
 }
示例#6
0
 /// <summary>
 /// Appends a geometry data object to the Mesh, returns false if the mesh would become too big and needs splitting
 /// </summary>
 /// <param name="geometryMeshData"></param>
 public bool Add(XbimGeometryData geometryMeshData)
 {
     XbimMatrix3D transform = geometryMeshData.Transform;
     if (geometryMeshData.GeometryType == XbimGeometryType.TriangulatedMesh)
     {
         XbimTriangulatedModelStream strm = new XbimTriangulatedModelStream(geometryMeshData.ShapeData);
         XbimMeshFragment fragment = strm.BuildWithNormals(this, transform);
         if (fragment.EntityLabel==int.MinValue) //nothing was added due to size being exceeded
             return false;
         else //added ok
         {
             fragment.EntityLabel = geometryMeshData.IfcProductLabel;
             fragment.EntityType = IfcMetaData.GetType(geometryMeshData.IfcTypeId);
             meshes.Add(fragment);
         }
     }
     else if (geometryMeshData.GeometryType == XbimGeometryType.BoundingBox)
     {
         XbimRect3D r3d = XbimRect3D.FromArray(geometryMeshData.ShapeData);
         this.Add(XbimMeshGeometry3D.MakeBoundingBox(r3d, transform), geometryMeshData.IfcProductLabel, IfcMetaData.GetType(geometryMeshData.IfcTypeId));
     }
     else
         throw new XbimException("Illegal geometry type found");
     return true;
 }
 /// <summary>
 /// Do not use this rather create a XbimMeshGeometry3D first and construc this from it, appending WPF collections is slow
 /// </summary>
 /// <param name="geometryMeshData"></param>
 public void Append(XbimGeometryData geometryMeshData)
 {
     throw new NotImplementedException();
 }
        /// <summary>
        /// Get the space name holding the element
        /// </summary>
        /// <param name="el">IfcElement to get containing space for</param>
        /// <returns>Space name</returns>
        internal string GetSpaceHoldingElement(IfcElement el)
        {
            //see if we have space information, if not fill information list
            if (SpaceBoundingBoxInfo.Count == 0)
            {
                if (ifcSpaces == null)
                {
                    ifcSpaces = Model.Instances.OfType <IfcSpace>().ToList();
                }

                //get Geometry for spaces
                SpaceBoundingBoxInfo = Model.GetGeometryData(XbimGeometryType.BoundingBox)
                                       .Where(bb => bb.IfcTypeId == IfcMetaData.IfcTypeId(typeof(IfcSpace)))
                                       .Select(bb => new SpaceInfo
                {
                    Rectangle = XbimRect3D.FromArray(bb.ShapeData),
                    Matrix    = XbimMatrix3D.FromArray(bb.DataArray2),
                    Name      = ifcSpaces.Where(sp => (sp.EntityLabel == bb.IfcProductLabel)).Select(sp => sp.Name.ToString()).FirstOrDefault()
                }).ToList();
            }


            string spaceName = string.Empty;

            //only if we have any space information
            if (SpaceBoundingBoxInfo.Any())
            {
                //find the IfcElement Bounding Box and To WCS Matrix
                XbimGeometryData elGeoData = Model.GetGeometryData(el, XbimGeometryType.BoundingBox).FirstOrDefault();
                //check to see if we have any geometry within the file
                if (elGeoData == null)
                {
                    return(string.Empty); //No geometry
                }
                XbimRect3D   elBoundBox    = XbimRect3D.FromArray(elGeoData.ShapeData);
                XbimMatrix3D elWorldMatrix = XbimMatrix3D.FromArray(elGeoData.DataArray2);
                //Get object space top and bottom points of the bounding box
                List <XbimPoint3D> elBoxPts = new List <XbimPoint3D>();
                elBoxPts.Add(new XbimPoint3D(elBoundBox.X, elBoundBox.Y, elBoundBox.Z));
                elBoxPts.Add(new XbimPoint3D(elBoundBox.X + elBoundBox.SizeX, elBoundBox.Y + elBoundBox.SizeY, elBoundBox.Z + elBoundBox.SizeZ));
                elBoxPts.Add(elBoundBox.Centroid());

                //convert points of the bounding box to WCS
                IEnumerable <XbimPoint3D> elBoxPtsWCS = elBoxPts.Select(pt => elWorldMatrix.Transform(pt));
                //see if we hit any spaces
                spaceName = GetSpaceFromPoints(elBoxPtsWCS);
                //if we failed to get space on min points then use the remaining corner points
                if (string.IsNullOrEmpty(spaceName))
                {
                    XbimPoint3D elMinPt = elBoxPts[0];
                    XbimPoint3D elMaxPt = elBoxPts[1];
                    //elBoxPts.Clear(); //already tested points in list so clear them

                    //Extra testing on remaining corner points on the top and bottom plains
                    elBoxPts.Add(new XbimPoint3D(elMaxPt.X, elMaxPt.Y, elMinPt.Z));
                    elBoxPts.Add(new XbimPoint3D(elMaxPt.X, elMinPt.Y, elMinPt.Z));
                    elBoxPts.Add(new XbimPoint3D(elMinPt.X, elMaxPt.Y, elMinPt.Z));
                    elBoxPts.Add(new XbimPoint3D((elMaxPt.X - elMinPt.X) / 2.0, (elMaxPt.Y - elMinPt.Y) / 2.0, elMinPt.Z)); //centre face point

                    elBoxPts.Add(new XbimPoint3D(elMinPt.X, elMinPt.Y, elMaxPt.Z));
                    elBoxPts.Add(new XbimPoint3D(elMaxPt.X, elMinPt.Y, elMaxPt.Z));
                    elBoxPts.Add(new XbimPoint3D(elMinPt.X, elMaxPt.Y, elMaxPt.Z));
                    elBoxPts.Add(new XbimPoint3D((elMaxPt.X - elMinPt.X) / 2.0, (elMaxPt.Y - elMinPt.Y) / 2.0, elMaxPt.Z)); //centre face point
                    //convert points of the bounding box to WCS
                    elBoxPtsWCS = elBoxPts.Select(pt => elWorldMatrix.Transform(pt));
                    //see if we hit any spaces
                    spaceName = GetSpaceFromPoints(elBoxPtsWCS);
                }
                if (string.IsNullOrEmpty(spaceName))
                {
                    //Get tolerance size from element, 1% of smallest side size
                    double tol = elBoundBox.SizeX * 0.001;
                    if ((elBoundBox.SizeY * 0.001) < tol)
                    {
                        tol = elBoundBox.SizeY * 0.001;
                    }
                    if ((elBoundBox.SizeZ * 0.001) < tol)
                    {
                        tol = elBoundBox.SizeZ * 0.001;
                    }
                    if ((tol == 0.0) && //if tol 0.0
                        ((Context.WorkBookUnits.LengthUnit.Equals("meters", StringComparison.OrdinalIgnoreCase)) ||
                         (Context.WorkBookUnits.LengthUnit.Equals("metres", StringComparison.OrdinalIgnoreCase))
                        )
                        )
                    {
                        tol = 0.001;
                    }

                    spaceName = GetSpaceFromClosestPoints(elBoxPtsWCS, tol);
                }
            }
            return(spaceName);
        }
 /// <summary>
 /// Appends a geometry data object to the Mesh, returns false if the mesh would become too big and needs splitting
 /// </summary>
 /// <param name="geometryMeshData"></param>
 public bool Add(XbimGeometryData geometryMeshData, short modelId = 0)
 {
     var transform = XbimMatrix3D.FromArray(geometryMeshData.DataArray2);
     if (geometryMeshData.GeometryType == XbimGeometryType.TriangulatedMesh)
     {
         var strm = new XbimTriangulatedModelStream(geometryMeshData.ShapeData);
         var fragment = strm.BuildWithNormals(this, transform, modelId);
         if (fragment.EntityLabel == -1) //nothing was added due to size being exceeded
             return false;
         fragment.EntityLabel = geometryMeshData.IfcProductLabel;
         fragment.EntityTypeId = geometryMeshData.IfcTypeId;
         _meshes.Add(fragment);
     }
     else if (geometryMeshData.GeometryType == XbimGeometryType.BoundingBox)
     {
         var r3D = XbimRect3D.FromArray(geometryMeshData.ShapeData);
         Add(MakeBoundingBox(r3D, transform), geometryMeshData.IfcProductLabel, IfcMetaData.GetType(geometryMeshData.IfcTypeId), modelId);
     }
     else
         throw new XbimException("Illegal geometry type found");
     return true;
 }
示例#10
0
        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);
                    }

                    //get all the IfcDoors in the 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 to get the bounding box from
                        XbimGeometryData geoData = model.GetGeometryData(ifcDoor, XbimGeometryType.BoundingBox).FirstOrDefault();
                        if (geoData != null)
                        {
                            XbimRect3D boundBox = XbimRect3D.FromArray(geoData.ShapeData); //size information for the IfcDoor, but the information is for the bounding box which encloses the door

                            //if want want in World space
                            XbimMatrix3D worldMatrix = geoData.Transform;
                            //if we want to convert to World space we can use the geoData.Transform property and create the world matrix
                            XbimPoint3D MinPtOCS = new XbimPoint3D(boundBox.X, boundBox.Y, boundBox.Z);
                            XbimPoint3D MaxPtOCS = new XbimPoint3D(boundBox.X + boundBox.SizeX, boundBox.Y + boundBox.SizeY, boundBox.Z + boundBox.SizeZ);
                            //transformed values, may no longer a valid bounding box in the new space if any Pitch or Yaw, i.e. stairs ceiling supports
                            XbimPoint3D MinPtWCS = worldMatrix.Transform(MinPtOCS);
                            XbimPoint3D MaxPtWCS = worldMatrix.Transform(MaxPtOCS);
                            //if you product is at any angle to the World space then the bounding box can be recalculated,
                            //a example of this can be found here https://sbpweb.svn.codeplex.com/svn/SBPweb.Workbench/Workbench%20Framework%202.0.0.x/Presentation/Windows.WPF/Utils/Maths.cs
                            //in the TransformBounds function
                            Console.WriteLine("\n-------------Bounding Box Information-------------");
                            Console.WriteLine("Entity Type = {0}", IfcMetaData.GetType(geoData.IfcTypeId).Name);
                            Console.WriteLine("Entity Label = {0}", Math.Abs(ifcDoor.EntityLabel).ToString());
                            Console.WriteLine("Size X = {0:F2}", boundBox.SizeX.ToString());
                            Console.WriteLine("Size Y = {0:F2}", boundBox.SizeY.ToString());
                            Console.WriteLine("Size Z = {0:F2}", boundBox.SizeZ.ToString());
                            Console.WriteLine("Object space minimum point {0}", MinPtOCS);
                            Console.WriteLine("Object space maximum point {0}", MaxPtOCS);
                            Console.WriteLine("World space minimum point {0}", MinPtWCS);
                            Console.WriteLine("World space maximum point {0}", MaxPtWCS);
                            Console.WriteLine("---------------------------------------------");
                        }
                    }
                    else
                    {
                        Console.WriteLine(string.Format("Failed to find any IfcDoor's in {0}", ifcFile));
                        return;  //exit
                    }
                }
            }
            else
            {
                Console.WriteLine(string.Format("Failed to find {0} in executable directory", ifcFile));
            }
            Console.WriteLine("\nFinished");
        }
示例#11
0
 /// <summary>
 /// Do not use this rather create a XbimMeshGeometry3D first and construct this from it, appending WPF collections is slow
 /// </summary>
 /// <param name="geometryMeshData"></param>
 /// <param name="modelId"></param>
 public bool Add(XbimGeometryData geometryMeshData, short modelId)
 {
     throw new NotImplementedException();
 }
示例#12
0
 /// <summary>
 /// Do not use this rather create a XbimMeshGeometry3D first and construc this from it, appending WPF collections is slow
 /// </summary>
 /// <param name="geometryMeshData"></param>
 public void Append(XbimGeometryData geometryMeshData)
 {
     throw new NotImplementedException();
 }