/// <summary>
        /// Clears the current graphics and initiates the cascade of events that result in viewing the scene.
        /// </summary>
        /// <param name="EntityLabels">If null loads the whole model, otherwise only elements listed in the enumerable</param>
        public void LoadGeometry(XbimModel model, bool recalcView = true)
        {
            // AddLayerToDrawingControl is the function that actually populates the geometry in the viewer.
            // AddLayerToDrawingControl is triggered by BuildRefModelScene and BuildScene below here when layers get ready.

            //reset all the visuals
            ClearGraphics(recalcView);
            short userDefinedId = 0;

            if (model == null)
            {
                return; //nothing to show
            }
            model.UserDefinedId = userDefinedId;
            Xbim3DModelContext context = new Xbim3DModelContext(model);
            XbimRegion         largest = context.GetLargestRegion();
            XbimPoint3D        c       = new XbimPoint3D(0, 0, 0);
            XbimRect3D         bb      = XbimRect3D.Empty;

            if (largest != null)
            {
                bb = new XbimRect3D(largest.Centre, largest.Centre);
            }

            foreach (var refModel in model.ReferencedModels)
            {
                XbimRegion r;
                refModel.Model.UserDefinedId = ++userDefinedId;

                Xbim3DModelContext refContext = new Xbim3DModelContext(refModel.Model);
                r = refContext.GetLargestRegion();

                if (r != null)
                {
                    if (bb.IsEmpty)
                    {
                        bb = new XbimRect3D(r.Centre, r.Centre);
                    }
                    else
                    {
                        bb.Union(r.Centre);
                    }
                }
            }
            XbimPoint3D p = bb.Centroid();

            _modelTranslation = new XbimVector3D(-p.X, -p.Y, -p.Z);
            model.ReferencedModels.CollectionChanged += RefencedModels_CollectionChanged;
            //build the geometric scene and render as we go
            BuildScene(context);
            foreach (var refModel in model.ReferencedModels)
            {
                Xbim3DModelContext refContext = new Xbim3DModelContext(refModel.Model);
                BuildScene(refContext);
            }
            if (recalcView)
            {
                RecalculateView(model);
            }
        }
        public XbimModelPositioning(IModel model)
        {
            _model = model;
            var geomStore = model.GeometryStore;

            if (_model.GeometryStore.IsEmpty)
            {
                return;
            }
            using (var reader = geomStore.BeginRead())
            {
                var regions = reader.ContextRegions.Where(cr => cr.MostPopulated() != null).Select(c => c.MostPopulated());
                var rect    = XbimRect3D.Empty;
                int pop     = 0;
                foreach (var r in regions)
                {
                    pop += r.Population;
                    if (rect.IsEmpty)
                    {
                        rect = r.ToXbimRect3D();
                    }
                    else
                    {
                        rect.Union(r.ToXbimRect3D());
                    }
                }
                if (pop > 0)
                {
                    LargestRegion = new XbimRegion("Largest", rect, pop);
                }
            }
        }
Example #3
0
 public static Region ToRegion(this XbimRegion r, double scale = 1.0, Func <XbimPoint3D, XbimPoint3D> adapter = null)
 {
     return(new Region
     {
         BoundingBox = r.ToXbimRect3D().ToBoundingBox(scale, adapter),
         Population = r.Population,
         Label = r.Name
     });
 }
 public MyBimRegion(int population, float px, float py, float pz, float sx, float sy, float sz)
 {
     this.population = population;
     this.position   = new Vector3(px, py, pz);
     this.scale      = new Vector3(sx, sy, sz);
     xbimRegion      = new XbimRegion()
     {
         Population = population,
         Centre     = new XbimPoint3D(px, py, pz),
         Size       = new XbimVector3D(sx, sy, sz)
     };
 }
Example #5
0
 public BimRegion(int population, float centreX, float centreY, float centreZ, float sizeX, float sizeY, float sizeZ)
 {
     this.population = population;
     this.position   = new Vector3(centreX, centreY, centreZ);
     this.size       = new Vector3(sizeX, sizeY, sizeZ);
     xbimRegion      = new XbimRegion()
     {
         Population = population,
         Centre     = new XbimPoint3D(centreX, centreY, centreZ),
         Size       = new XbimVector3D(sizeX, sizeY, sizeZ)
     };
 }
Example #6
0
        private XbimRegion Merge(XbimRegion selectedRegion, XbimRegion reg)
        {
            var s1 = MinMaxPoints(selectedRegion);
            var s2 = MinMaxPoints(reg);
            var r1 = new XbimRect3D(s1[0], s1[1]);
            var r2 = new XbimRect3D(s2[0], s2[1]);

            r1.Union(r2);
            var merged = new XbimRegion("Merged", r1, selectedRegion.Population + reg.Population);

            return(merged);
        }
Example #7
0
        private XbimPoint3D[] MinMaxPoints(XbimRegion rect, double oneMeter = 1.0)
        {
            var pMin = new XbimPoint3D(
                (rect.Centre.X - (rect.Size.X / 2)) / oneMeter,
                (rect.Centre.Y - (rect.Size.Y / 2)) / oneMeter,
                (rect.Centre.Z - (rect.Size.Z / 2)) / oneMeter
                );

            var pMax = new XbimPoint3D(
                (rect.Centre.X + (rect.Size.X / 2)) / oneMeter,
                (rect.Centre.Y + (rect.Size.Y / 2)) / oneMeter,
                (rect.Centre.Z + (rect.Size.Z / 2)) / oneMeter
                );

            return(new[] { pMin, pMax });
        }
Example #8
0
        public XbimModelPositioning(XbimModel model)
        {
            _model  = model;
            Context = new Xbim3DModelContext(model);
            var supportLevel = model.GeometrySupportLevel;

            switch (supportLevel)
            {
            case 1:
                LargestRegion = GetLargestRegion(model);
                break;

            case 2:
                LargestRegion = Context.GetLargestRegion();
                break;
            }
        }
Example #9
0
        private XbimRegion Merge(XbimRegion reg1, XbimRegion reg2)
        {
            // todo: needs to review the merge function to consider region's WorldCoordinateSystem
            //
            var s1 = MinMaxPoints(reg1);
            var s2 = MinMaxPoints(reg2);
            var r1 = new XbimRect3D(s1[0], s1[1]);
            var r2 = new XbimRect3D(s2[0], s2[1]);

            r1.Union(r2);
            var merged = new XbimRegion(
                "Merged",
                r1,
                reg1.Population + reg2.Population,
                reg1.WorldCoordinateSystem
                );

            return(merged);
        }
Example #10
0
        // Compute contexts and related transformation
        private void ComputeContextTransforms(IGeometryStoreReader gReader, IfcSceneExportSummary s, IDictionary <int, SceneContext> contextTable)
        {
            foreach (var cr in gReader.ContextRegions)
            {
                SceneContext sc;
                if (contextTable.TryGetValue(cr.ContextLabel, out sc))
                {
                    XbimVector3D offset = XbimVector3D.Zero;
                    XbimVector3D mean   = XbimVector3D.Zero;
                    foreach (var r in cr)
                    {
                        mean += r.Centre.ToVector();
                        sc.Regions.Add(r.ToRegion(s.Scale));
                    }
                    mean *= 1.0 / cr.Count;

                    switch (s.AppliedSettings.Positioning)
                    {
                    case ScenePositioningStrategy.UserCorrection:
                        // Center at user's center
                        offset = s.AppliedSettings.UserModelCenter.ToXbimVector3DMeter(s.Model.ModelFactors);
                        break;

                    case ScenePositioningStrategy.MostPopulatedRegionCorrection:
                        // Center at most populated
                        offset = cr.MostPopulated().Centre.ToVector();
                        break;

                    case ScenePositioningStrategy.MostExtendedRegionCorrection:
                        // Center at largest
                        offset = cr.Largest().Centre.ToVector();
                        break;

                    case ScenePositioningStrategy.MeanTranslationCorrection:
                        // Use mean correction
                        offset = mean;
                        break;

                    case ScenePositioningStrategy.SignificantPopulationCorrection:
                        var        population = cr.Sum(r => r.Population);
                        XbimRegion rs         = null;
                        double     max        = double.NegativeInfinity;
                        foreach (var r in cr)
                        {
                            // Compute weighted extent by relative population
                            double factor = r.Size.Length * r.Population / population;
                            if (max < factor)
                            {
                                rs  = r;
                                max = factor;
                            }
                        }
                        offset = rs.Centre.ToVector();
                        break;

                    case ScenePositioningStrategy.NoCorrection:
                        // No correction
                        Logger?.LogInformation($"No translation correction applied by settings to context '{cr.ContextLabel}'");
                        break;

                    default:
                        throw new NotImplementedException($"Missing implementation for '{s.AppliedSettings.Positioning}'");
                    }

                    if (s.AppliedSettings.Transforming == SceneTransformationStrategy.Matrix)
                    {
                        // If Matrix or Global use rotation matrix representation
                        sc.Wcs = new XbimMatrix3D(offset).ToRotation(s.Scale);
                    }
                    else
                    {
                        // Otherwise use Quaternion representation
                        sc.Wcs = new XbimMatrix3D(offset).ToQuaternion(s.Scale);
                    }

                    // Set correction to negative offset shift (without scale since in model space units)
                    s.SetRepresentationContext(cr.ContextLabel, sc, new XbimMatrix3D(offset * -1));
                }
                else
                {
                    Logger?.LogWarning("Excluding context label '{0}'. Not mentioned by settings.", cr.ContextLabel);
                }
            }
        }
Example #11
0
        /// <summary>
        /// Initialises the position class and
        /// </summary>
        /// <param name="model"></param>
        public XbimModelPositioning(IModel model)
        {
            _model = model;
            var geomStore = model.GeometryStore;

            if (_model.GeometryStore.IsEmpty)
            {
                return;
            }
            var gc = new Xbim3DModelContext(_model);

            using (var reader = geomStore.BeginRead())
            {
                // ContextRegions is a collection of ContextRegions, which is also a collection.
                // we get the most populated from each
                var name          = "MostPopulated";
                var regions       = reader.ContextRegions.Where(cr => cr.MostPopulated() != null).Select(c => c.MostPopulated());
                var rect          = XbimRect3D.Empty;
                var pop           = 0;
                var mergedRegions = new List <XbimRegion>();
                // then perform their union
                foreach (var r in regions)
                {
                    mergedRegions.Add(r);
                    pop += r.Population;
                    if (rect.IsEmpty)
                    {
                        rect = r.ToXbimRect3D();
                        name = r.Name;
                    }
                    else
                    {
                        rect.Union(r.ToXbimRect3D());
                    }
                }

                if (pop <= 0)
                {
                    return;
                }
                // look at expanding the region to any other that might be visible in the viewspace
                //
                var threshold        = 5;
                var selectedRad      = rect.Radius() * threshold;
                var testOtherRegions = true;
                while (testOtherRegions)
                {
                    testOtherRegions = false;
                    foreach (var contextRegion in reader.ContextRegions)
                    {
                        foreach (var otherRegion in contextRegion.Where(x => !mergedRegions.Contains(x)))
                        {
                            var otherRad       = otherRegion.Size.Length / 2;
                            var centreDistance = GetDistance(otherRegion.Centre, rect.Centroid());
                            if (otherRad + selectedRad > centreDistance)
                            {
                                mergedRegions.Add(otherRegion);
                                pop += otherRegion.Population;
                                rect.Union(otherRegion.ToXbimRect3D());
                                testOtherRegions = true;
                                selectedRad      = rect.Radius() * threshold;
                            }
                        }
                    }
                }
                // todo: the identity matrix should be replaced with a correct model matrix.
                //
                SelectedRegion = new XbimRegion(name, rect, pop, XbimMatrix3D.Identity);
            }
        }