/***************************************************/ /**** 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); }
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); }
/***************************************************/ /**** 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); }