Пример #1
0
        /***************************************************/
        /**** Public Methods                            ****/
        /***************************************************/

        public static CompositeGeometry Geometry3D(this SpatialSpecification spatialSpec)
        {
            return(new CompositeGeometry()
            {
                Elements = SpatialBoundingBoxes(spatialSpec).OfType <IGeometry>().ToList()
            });
        }
        public static List <SpatialSpecification> SpatialSpecifications(List <IObject> referenceElements, List <ZoneSpecification> zoneSpecifications, string prop = "ZoneName")
        {
            List <SpatialSpecification> result = new List <SpatialSpecification>();

            var zoneLocations = new Dictionary <string, List <IObject> >();

            bool missingProp = false;

            foreach (var refElem in referenceElements)
            {
                string zoneName = refElem.ValueFromSource("ZoneName") as string;

                if (string.IsNullOrWhiteSpace(zoneName))
                {
                    missingProp = true;
                    continue;
                }

                if (!zoneLocations.ContainsKey(zoneName))
                {
                    zoneLocations[zoneName] = new List <IObject>();
                }

                zoneLocations[zoneName].Add(refElem);
            }

            if (missingProp)
            {
                BH.Engine.Reflection.Compute.RecordError($"Some {nameof(referenceElements)} object did not have the required `{prop}` property in its CustomData.");
            }

            Dictionary <string, ZoneSpecification> zoneDic = zoneSpecifications.GroupBy(z => z.ZoneName).ToDictionary(g => g.Key, g => g.FirstOrDefault());
            HashSet <string> zoneSpecsNotFound             = new HashSet <string>();

            foreach (string zoneName in zoneLocations.Keys)
            {
                SpatialSpecification sp = new SpatialSpecification();
                sp.Locations = zoneLocations[zoneName];
                if (!zoneDic.ContainsKey(zoneName))
                {
                    zoneSpecsNotFound.Add(zoneName);
                    continue;
                }

                sp.ZoneSpecification = zoneDic[zoneName];

                result.Add(sp);
            }

            if (zoneSpecsNotFound.Count > 0)
            {
                foreach (var notFoundZoneName in zoneSpecsNotFound)
                {
                    BH.Engine.Reflection.Compute.RecordWarning($"No Zone specification was found for the Zone named `{notFoundZoneName}` that was required by some of the objects provided.");
                }
            }

            return(result);
        }
        public static SpatialSpecification SpatialSpecification(List <IObject> referenceElements, ZoneSpecification zoneSpecification, string prop = "ZoneName")
        {
            SpatialSpecification result = new SpatialSpecification();

            foreach (var loc in referenceElements)
            {
                string zoneName = Reflection.Query.PropertyValue(loc, "ZoneName") as string;

                if (zoneName == zoneSpecification.ZoneName)
                {
                    result.Locations.Add(loc);
                }
            }

            result.ZoneSpecification = zoneSpecification;

            return(result);
        }
        public static List <BoundingBox> SpatialBoundingBoxes(this SpatialSpecification spatialSpec)
        {
            List <BoundingBox> result = new List <BoundingBox>();

            List <IGeometry>  locations = spatialSpec.Locations.Select(l => BH.Engine.CIH.Query.IGeometry(l)).ToList();
            ZoneSpecification zoneSpec  = spatialSpec.ZoneSpecification;

            foreach (var loc in locations)
            {
                BoundingBox bb = Query.IElementBoundingBox(loc, zoneSpec.Width, zoneSpec.Height, zoneSpec.Depth);

                if (bb != null)
                {
                    result.Add(bb);
                }
            }

            return(result);
        }
Пример #5
0
        private static Dictionary <BHoMObject, BoundingBox> FilterObjects(List <BHoMObject> objects, SpatialSpecification spatialSpec)
        {
            Dictionary <BHoMObject, BoundingBox> passedObj_zoneBox = new Dictionary <BHoMObject, BoundingBox>();

            Dictionary <BHoMObject, IGeometry> objsGeometry = new Dictionary <BHoMObject, IGeometry>();

            // Compute the geometry for each object.
            foreach (var obj in objects)
            {
                BHoMObject bhomObj = obj as BHoMObject;
                IGeometry  geom    = BH.Engine.Base.Query.IGeometry(bhomObj);

                if (geom == null)
                {
                    BH.Engine.Reflection.Compute.RecordWarning($"Could not Query the Geometry out of a given {bhomObj.GetType().Name}.");
                    continue;
                }

                objsGeometry[bhomObj] = geom;
            }

            // Filter objects based on the spatialSpecifications.
            ZoneSpecification zoneSpec = spatialSpec.ZoneSpecification;

            // A bounding box is calculated per each object as defined by the individual ZoneSpecification
            Dictionary <BHoMObject, BoundingBox> bbPerObj = new Dictionary <BHoMObject, BoundingBox>();
            List <BoundingBox> allZoneBoxes = spatialSpec.SpatialBoundingBoxes();

            foreach (BHoMObject bhomObj in objsGeometry.Keys)
            {
                // Check if any of the Specification's boundingBoxes contains the object
                foreach (var zoneBB in allZoneBoxes)
                {
                    if (zoneBB.IsContaining(objsGeometry[bhomObj]))
                    {
                        // If the zone bounding box contains the bhomObject's Geometry, let's apply the other filters.
                        var res = VerifyCondition(new List <object>()
                        {
                            bhomObj
                        }, new LogicalCondition()
                        {
                            Conditions = zoneSpec.FilterConditions
                        });
                        if (res.PassedObjects.Count == 1) // if the object passed all the provided Conditions, then it's passed.
                        {
                            passedObj_zoneBox[res.PassedObjects.First() as BHoMObject] = zoneBB;
                        }
                    }
                }
            }

            return(passedObj_zoneBox);
        }
Пример #6
0
        /***************************************************/
        /**** Private Methods                           ****/
        /***************************************************/

        private static SpecificationResult VerifySpecification(List <object> objects, SpatialSpecification spatialSpec)
        {
            SpecificationResult specResult = new SpecificationResult();

            specResult.NotAssessedObjects = objects.Where(o => !(o is BHoMObject)).ToList();

            // Apply filters.
            ConditionResult filterResultAggregated = new ConditionResult();

            List <BHoMObject> bhomObjs = objects.OfType <BHoMObject>().ToList();

            Dictionary <BHoMObject, BoundingBox> passedObjs_bb = FilterObjects(bhomObjs, spatialSpec);

            filterResultAggregated.PassedObjects = passedObjs_bb.Keys.OfType <object>().ToList();
            filterResultAggregated.FailedObjects = bhomObjs.Except(passedObjs_bb.Keys).OfType <object>().ToList();

            // Apply checks.
            ConditionResult checkResultAggregated = new ConditionResult();

            foreach (var kv in passedObjs_bb)
            {
                BHoMObject  objToCheck = kv.Key;
                BoundingBox zoneBB     = kv.Value;
                IGeometry   geom3D     = BH.Engine.Base.Query.IGeometry3D(kv.Key);

                if (geom3D == null)
                {
                    BH.Engine.Reflection.Compute.RecordWarning($"Could not retrieve the Geometry3D for an object of type `{kv.Key.GetType().Name}`. The object will not be assessed.");
                    filterResultAggregated.FailedObjects.Add(kv.Key);
                    filterResultAggregated.PassedObjects.Remove(kv.Key);
                    continue;
                }

                bool isContained = zoneBB.IsContaining(geom3D);

                if (!isContained)
                {
                    checkResultAggregated.FailInfo.Add("The 3D geometry of the object is not contained in the Zone.");
                }

                var checkResult_obj = VerifyConditions(new List <object>()
                {
                    objToCheck
                }, spatialSpec.ZoneSpecification.CheckConditions);
                if (isContained)
                {
                    checkResultAggregated.PassedObjects.AddRange(checkResult_obj.PassedObjects);
                    checkResultAggregated.FailedObjects.AddRange(checkResult_obj.FailedObjects);
                    checkResultAggregated.Condition = checkResult_obj.Condition;
                }
                else
                {
                    checkResultAggregated.FailedObjects.Add(objToCheck);
                    List <ICondition> failedConditions = new List <ICondition> {
                        new IsInBoundingBox()
                        {
                            BoundingBox = zoneBB
                        }
                    };
                    failedConditions.AddRange(spatialSpec.ZoneSpecification.CheckConditions);
                    checkResultAggregated.Condition = new LogicalCondition()
                    {
                        Conditions = failedConditions
                    };
                }

                checkResultAggregated.FailInfo.AddRange(checkResult_obj.FailInfo);
            }

            var aggregatedRes = PopulateSpecificationResult(spatialSpec, filterResultAggregated, checkResultAggregated);

            return(aggregatedRes);
        }