Загрузка данных


using System;
using System.Collections.Generic;
using System.Linq;
using Xbim.Ifc;
using Xbim.Ifc4.Interfaces;
using Xbim.Common;

namespace IfcBimEditor
{
    public sealed class ElementItem
    {
        public IIfcObject Element { get; set; }
        public string Display => $"{Element.ExpressType.Name} | {Element.Name} | {Element.GlobalId}";
    }

    public static class IfcEditor
    {
        public static List<IIfcObject> FindSimilar(IfcStore model, IIfcObject selected, int mode)
        {
            var all = model.Instances.OfType<IIfcObject>();
            switch (mode)
            {
                case 1:
                    return all.Where(x => string.Equals(
                        x.Name?.ToString(), selected.Name?.ToString(),
                        StringComparison.OrdinalIgnoreCase)).ToList();
                case 2:
                    var type = selected.IsTypedBy.FirstOrDefault()?.RelatingType;
                    return type == null
                        ? new List<IIfcObject> { selected }
                        : all.Where(x => x.IsTypedBy.Any(r =>
                            r.RelatingType != null && r.RelatingType.GlobalId == type.GlobalId)).ToList();
                default:
                    return all.Where(x => x.ExpressType.Name == selected.ExpressType.Name).ToList();
            }
        }

        public static int SetStringProperty(IfcStore model, IEnumerable<IIfcObject> objects,
            string psetName, string propertyName, string value, bool createMissing)
        {
            if (string.IsNullOrWhiteSpace(psetName) || string.IsNullOrWhiteSpace(propertyName))
                throw new ArgumentException("Укажите имя набора свойств и свойства.");

            var targets = objects.Distinct().ToList();
            int changed = 0;
            using (var tx = model.BeginTransaction("Bulk property edit"))
            {
                foreach (var obj in targets)
                {
                    var relation = obj.IsDefinedBy
                        .OfType<IIfcRelDefinesByProperties>()
                        .FirstOrDefault(r => r.RelatingPropertyDefinition is IIfcPropertySet ps &&
                                             ps.Name?.ToString() == psetName);
                    var set = relation?.RelatingPropertyDefinition as IIfcPropertySet;
                    var existing = set?.HasProperties
                        .OfType<IIfcPropertySingleValue>()
                        .FirstOrDefault(p => p.Name?.ToString() == propertyName);
                    if (existing == null && !createMissing) continue;

                    // Отдельный Pset предотвращает изменение свойств других объектов.
                    var newSet = model.Instances.New<Xbim.Ifc4.Kernel.IfcPropertySet>(p =>
                    {
                        p.Name = psetName;
                    });
                    if (set != null)
                    {
                        foreach (var oldProp in set.HasProperties)
                        {
                            if (oldProp.Name?.ToString() == propertyName) continue;
                            var copy = model.InsertCopy((IPersistEntity)oldProp,
                                new Xbim.Common.XbimInstanceHandleMap(model, model), null, false, false);
                            newSet.HasProperties.Add((IIfcProperty)copy);
                        }
                    }
                    newSet.HasProperties.Add(model.Instances.New<Xbim.Ifc4.PropertyResource.IfcPropertySingleValue>(p =>
                    {
                        p.Name = propertyName;
                        p.NominalValue = new Xbim.Ifc4.MeasureResource.IfcText(value);
                    }));
                    model.Instances.New<Xbim.Ifc4.Kernel.IfcRelDefinesByProperties>(r =>
                    {
                        r.RelatingPropertyDefinition = newSet;
                        r.RelatedObjects.Add(obj);
                    });
                    if (relation != null)
                    {
                        relation.RelatedObjects.Remove(obj);
                        if (!relation.RelatedObjects.Any()) model.Delete((IPersistEntity)relation);
                    }
                    changed++;
                }
                tx.Commit();
            }
            return changed;
        }
    }
}