コード例 #1
0
ファイル: ToRelation.cs プロジェクト: BHoM/BHoM_Engine
        public static List<IRelation> ToRelation(this IBHoMObject obj)
        {
            if(obj == null)
            {
                BH.Engine.Reflection.Compute.RecordError("Cannot convert a null BHoM object to a relation.");
                return new List<IRelation>();
            }

            List<IRelation> relations = new List<IRelation>();

            List<IFragment> dependencyFragments = obj.GetAllFragments(typeof(IDependencyFragment));
            foreach (IDependencyFragment dependency in dependencyFragments)
                relations.AddRange(dependency.IToRelation(obj.BHoM_Guid));

            return relations;
        }
コード例 #2
0
        private static ConditionResult VerifyCondition(List <object> objects, FragmentCondition fragmentCondition)
        {
            ConditionResult result = new ConditionResult()
            {
                Condition = fragmentCondition
            };

            foreach (var obj in objects)
            {
                IBHoMObject bhomObj = obj as IBHoMObject;

                if (bhomObj != null && !IsAnyConditionNull(fragmentCondition.Condition, nameof(FragmentCondition) + "." + nameof(FragmentCondition.Condition)))
                {
                    // If there is only one fragment of the specified type, no problem, the check will be done on it.
                    // If the specified type is a parent type, all fragments of that type will be retrieved:
                    // the condition will have to be satisfied for all fragments (forced AND).
                    // To have an OR condition on the child fragments,
                    // multiple conditions that target the individual fragment child type combined with a logical OR condition is needed.
                    List <IFragment> fragments = bhomObj.GetAllFragments(fragmentCondition.FragmentType);

                    ConditionResult subConditionResult = new ConditionResult();
                    subConditionResult = IVerifyCondition(fragments.OfType <object>().ToList(), fragmentCondition.Condition);

                    // Forced AND on all child fragments. See comment above.
                    if (subConditionResult.Pattern.TrueForAll(v => v == true))
                    {
                        result.PassedObjects.Add(obj);
                        result.Pattern.Add(true);
                    }
                    else
                    {
                        result.FailedObjects.Add(obj);
                        result.Pattern.Add(false);
                    }
                }
                else
                {
                    // If the object is not a BHoMObject, the condition can't apply to it.
                    result.FailedObjects.Add(obj);
                    result.Pattern.Add(false);
                }
            }
            return(result);
        }
コード例 #3
0
        public static string Hash(this IObject iObj, ComparisonConfig comparisonConfig = null, bool hashFromFragment = false)
        {
            if (iObj == null)
            {
                BH.Engine.Reflection.Compute.RecordError("Cannot query the hash of a null object.");
                return("");
            }

            if (hashFromFragment && iObj is IBHoMObject)
            {
                // Instead of computing the Hash, first tryGet the hash in HashFragment
                string hash = (iObj as IBHoMObject).FindFragment <HashFragment>()?.Hash;

                if (!string.IsNullOrWhiteSpace(hash))
                {
                    return(hash);
                }
            }

            // ------ SET UP OF CONFIGURATION ------

            // Make sure we always have a config object. Clone for immutability.
            ComparisonConfig cc = comparisonConfig == null ? new ComparisonConfig() : comparisonConfig.DeepClone();

            // Make sure that "BHoM_Guid" is added to the PropertyExceptions of the config.
            cc.PropertyExceptions = cc.PropertyExceptions ?? new List <string>();
            if (!cc.PropertyExceptions.Contains(nameof(BHoMObject.BHoM_Guid)))
            {
                cc.PropertyExceptions.Add(nameof(BHoMObject.BHoM_Guid));
            }

            // Process the "PropertiesToInclude" property.
            if (cc.PropertiesToConsider?.Any() ?? false)
            {
                // The hash computation can only consider "exceptions".
                // We need to retrieve all the object properties, intersect them with PropertiesToInclude, and treat all those remaining as "exceptions".
                // Works only for top-level properties.
                IEnumerable <string> exceptions = BH.Engine.Reflection.Query.PropertyNames(iObj).Except(cc.PropertiesToConsider);
                cc.PropertyExceptions.AddRange(exceptions);
            }

            // Make sure that the single Property exceptions are either:
            // - explicitly referring to a property in its "property path": e.g. Bar.StartNode.Point.X
            // - OR if it's only a property name e.g. BHoM_Guid make sure that we prepend the wildcard so we can match the single property inside any property path: e.g. *BHoM_Guid
            //cc.PropertyExceptions = cc.PropertyExceptions.Select(pe => pe = pe.Contains('.') ? pe : "*" + pe).ToList();

            // Convert from the Numeric Tolerance to fractionalDigits (required for the hash).
            int fractionalDigits = Math.Abs(Convert.ToInt32(Math.Log10(cc.NumericTolerance)));

            // ----- SET UP OF INPUT OBJECT -----

            // Copy the object for immutability
            IObject iObj_copy = iObj.ShallowClone();

            // Any HashFragment present on the object must not be considered when computing the Hash. Remove if present.
            IBHoMObject bhomobj = iObj_copy as IBHoMObject;

            if (bhomobj != null)
            {
                List <IHashFragment> hashFragments = bhomobj.GetAllFragments(typeof(IHashFragment)).OfType <IHashFragment>().ToList();
                hashFragments.ForEach(f => bhomobj.Fragments.Remove(f.GetType()));
                iObj_copy = bhomobj;
            }

            // ----- HASH -----

            // Compute the defining string.
            string hashString = DefiningString(iObj_copy, cc, fractionalDigits, 0);

            if (string.IsNullOrWhiteSpace(hashString))
            {
                // This means that:
                // - all properties of the input object were disregarded due to the settings specified in the ComparisonConfig, or
                // - all properties of the input object that were not disregarded were null or empty,
                // Since a hash has to be always returned, for this scenario we are forced to build a defining string out of the type full name.
                hashString = iObj_copy.GetType().FullName;
            }

            // Return the SHA256 hash of the defining string.
            return(SHA256Hash(hashString));
        }