Exemplo n.º 1
0
        /// <summary>
        /// Returns the list of Object in a IfcRelAssociatesMaterial with the specified material select.
        /// </summary>
        /// <param name="instanceCollection"></param>
        /// <param name="matSel">The material select to search.</param>
        /// <param name="deepSearch">
        /// True if the function needs to execute a deeper semantical analysis of the relations (it can expand the query result).
        /// False if a direct analysis of explicit associations with the specific MaterialSet.
        /// </param>
        public static IEnumerable <IIfcDefinitionSelect> GetInstancesOfMaterial(this IEntityCollection instanceCollection, IIfcMaterialSelect matSel, bool deepSearch)
        {
            // Debug.WriteLine(string.Format("GetInstance {0}, {1}", matSel.EntityLabel.ToString(), DeepSearch));
            if (matSel is IIfcMaterial)
            {
                // straight return of objects of all associations
                var assocs = instanceCollection.OfType <IIfcRelAssociatesMaterial>().Where(
                    x => x.RelatingMaterial.EntityLabel == matSel.EntityLabel
                    );
                foreach (var assoc in assocs)
                {
                    // ... and returns one object at a time in the enumerable
                    foreach (var item in assoc.RelatedObjects)
                    {
                        yield return(item);
                    }
                }
            }
            else if (matSel is IIfcMaterialLayer)
            {
                if (!deepSearch)
                {
                    // straight return of objects of all associations
                    var assocs = instanceCollection.OfType <IIfcRelAssociatesMaterial>().Where(
                        x => x.RelatingMaterial.EntityLabel == matSel.EntityLabel
                        );
                    foreach (var assoc in assocs)
                    {
                        // ... and returns one object at a time in the enumerable
                        foreach (var item in assoc.RelatedObjects)
                        {
                            yield return(item);
                        }
                    }
                }
                else // this is deep search
                {
                    foreach (var straightMatch in GetInstancesOfMaterial(instanceCollection, ((IIfcMaterialLayer)matSel).ToMaterialLayerSet, false))
                    {
                        yield return(straightMatch);
                    }
                }
            }
            else if (matSel is IIfcMaterialList)
            {
                if (!deepSearch)
                {
                    // straight return of objects of all associations
                    var assocs = instanceCollection.OfType <IIfcRelAssociatesMaterial>().Where(
                        x => x.RelatingMaterial.EntityLabel == matSel.EntityLabel
                        );
                    foreach (var assoc in assocs)
                    {
                        // ... and returns one object at a time in the enumerable
                        foreach (var item in assoc.RelatedObjects)
                        {
                            yield return(item);
                        }
                    }
                }
                else // this is deep search
                {
                    // a problem with this is that some exporters produce multiple IfcMaterialList that
                    // they share the same underlying set of Materials, so we are looking for a signature of the underlying materials.
                    //
                    var baseMatArray = ((IIfcMaterialList)matSel).Materials.Select(x => x.EntityLabel).ToArray(); // this is the signature.
                    var cmp          = EqualityComparer <int> .Default;
                    foreach (var testingMaterialList in instanceCollection.OfType <IIfcMaterialList>())
                    {
                        bool bDoesMatch;
                        if (testingMaterialList.EntityLabel == matSel.EntityLabel)
                        { // no need to compare
                            bDoesMatch = true;
                        }
                        else
                        {
                            var compMatArray = testingMaterialList.Materials.Select(x => x.EntityLabel).ToArray(); // this is the other signature.
                            bDoesMatch = ArraysEqual(baseMatArray, compMatArray, cmp);
                        }
                        if (bDoesMatch)
                        {
                            foreach (var straightMatch in GetInstancesOfMaterial(instanceCollection, testingMaterialList, false))
                            {
                                yield return(straightMatch);
                            }
                        }
                    }
                }
            }
            else if (matSel is IIfcMaterialLayerSet)
            {
                // no difference in deep mode available for this type

                // given a material layerset ...
                // ... search for all its usages modes ...
                var lsUsages = instanceCollection.OfType <IIfcMaterialLayerSetUsage>().Where(
                    x => x.ForLayerSet.EntityLabel == ((IIfcMaterialLayerSet)matSel).EntityLabel
                    );
                foreach (var lsUsage in lsUsages)
                {
                    // ... then for each usage mode, searches the relations with objects ...
                    foreach (var item in GetInstancesOfMaterial(instanceCollection, lsUsage, false))
                    {
                        yield return(item);
                    }
                }
            }
            else if (matSel is IIfcMaterialLayerSetUsage)
            {
                if (deepSearch)
                {
                    // identify the underlying material layer set and return all its usages.
                    foreach (var item in instanceCollection.GetInstancesOfMaterial(((IIfcMaterialLayerSetUsage)matSel).ForLayerSet, false))
                    {
                        yield return(item);
                    }
                }
                else
                {
                    // straight return of objects of all associations
                    var assocs = instanceCollection.OfType <IIfcRelAssociatesMaterial>().Where(
                        x => x.RelatingMaterial.EntityLabel == matSel.EntityLabel
                        );
                    foreach (var assoc in assocs)
                    {
                        // ... and returns one object at a time in the enumerable
                        foreach (var item in assoc.RelatedObjects)
                        {
                            yield return(item);
                        }
                    }
                }
            }
            else
            {
                Debugger.Break();
                Debug.WriteLine("Unexpected case");
            }
        }