Теперь Кью работает в режиме чтения

Мы сохранили весь контент, но добавить что-то новое уже нельзя
Архитектор, BIM-эксперт и Аналитик данных  · 11 нояб 2022

Тюнинг IFC-моделей. Добавляем Зоны (IfcZone). Часть 2.

Вторым названием данного поста могло бы быть: "Как вручную добавить пользовательские свойства в IFC-модель?". Мы на примере работы с Зонами посмотрим, как имплементируются пользовательские свойства в IFC.
Я напомню, в первой части мы начали вручную добавлять в IFC-модель зоны - сущности, которые группируют помещения, с целью предоставления каких-то укрупненных показателей, например, общей площади и другой подобной информации. Вот сейчас мы эту информацию и будем вносить в IFC. Но вначале разберёмся.
Концепция наборов свойств в IFC.
Класс IfcPropertyDefinition определяет обобщение всех характеристик (т.е. группировку отдельных свойств), которые могут быть присвоены объектам модели. Свойства по-отдельности не назначаются на объект, а группируются в отдельные наборы свойств. IfcPropertySet как раз и является таким контейнером, вмещающим в себя отдельные свойства. Он может быть присвоен самому объекту или его типу. Это разные понятия. Набор свойств (property set), присвоенный типу объекта, является общим для всех экземпляров одного и того же типа объекта (почти как в Renga).
У зон типов нет, поэтому будем присваивать набор свойств непосредственно на экземпляры.
Не будем ничего придумывать и возьмем стандартный набор пользовательских свойств Pset_ZoneCommon, в котором определены 6 свойств:
Смотрим сюда:
Перейти по ссылке
standards.buildingsmart.org/IFC/RELEASE/IFC4/ADD2_TC1/HTML/link/pset_zonecommon.htm
и видим, что свойства данного набора должны быть экземплярами класса IfcPropertySingleValue. Этот класс - наследник родительского класса IfcSimpleProperty (простые свойства)… глубже думаю лезть не стоит, этих свойств тьма-тьмущая.
При объявлении IfcPropertySingleValue мы должны определить 4 атрибута:
  1.  Name
  2. Description (optional)
  3. Nominal Value (optional)
  4. Unit (optional)
На языке EXPRESS это будет примерно так:
#260000= IFCPROPERTYSINGLEVALUE('Reference',$,'Zone1:Service_area - 252.56m^2',$);
#260001= IFCPROPERTYSINGLEVALUE('IsExternal',$,IFCBOOLEAN(.F.),$);
#260002= IFCPROPERTYSINGLEVALUE('GrossPlannedArea',$,252.56.,#9);
#260003= IFCPROPERTYSINGLEVALUE('NetPlannedArea',$,245.92,#9);
#260004= IFCPROPERTYSINGLEVALUE('PubliclyAccessible',$,IFCBOOLEAN(.T.),$);
#260005= IFCPROPERTYSINGLEVALUE('HandicapAccessible',$,IFCBOOLEAN(.F.),$);
Что из этого стоит отметить:
  1. Свойства идентифируются не GUID'ами (как объектные классы), а именем (Name), т.е. генерировать ничего не нужно, а просто дать понятное название.
  2. Булевые значения (TRUE или FALSE) записываются так: IFCBOOLEAN(.T.) или IFCBOOLEAN(.F.), соответственно с указыванием класса IfcBoolean (как вы уже поняли в спецификации IFC найдется класс для любого случая).
  3. Меры "GrossPlannedArea" и "NetPlannedArea"  (тип - IfcAreaMeasure) указываются с единицами измерения (Unit). В нашем случае - это квадратные метры, поскольку указываем площадь. Указываем ссылкой на строку, в которой данная единица измерения определена (#9). Renga сама записывает единицы измерения, которые используются в IFC-модели, надо лишь найти их в IFC-файле. В моем случае вот она (обычно в начале файла происходит объявление единиц измерений):
#9= IFCSIUNIT(*,.AREAUNIT.,$,.SQUARE_METRE.);
Переходим к созданию набора пользовательских свойств "Pset_ZoneCommon" и присвоению ему наших свойств:
#260010= IFCPROPERTYSET('1xk3AKjFr7YQ5mPmz2jS4Q',$,'Pset_ZoneCommon',$,(#260000,#260001,#260002,#260003,#260004,#260005));
При создании property set'а указываем значения 5 атрибутов:
  1. GlobalId
  2. OwnerHistory (optional)
  3. Name (optional)
  4. Description (optional)
  5. HasProperties
Присвоение свойств осуществляется через атрибут HasProperties класса IfcPropertySet. Там мы и указываем в скобках, через запятую ссылки на строки с объявленными свойствами. Ну и не забываем присвоить уникальный идентификатор в атрибуте GlobalId.
ВАЖНОЕ! Соглашение об именовании "Pset_Xxx" применяется ко всем наборам свойств, которые определены как часть спецификации IFC, и оно должно использоваться в качестве значения атрибута Name. Наборы свойств, которые не объявлены как часть спецификации IFC, т.е. пользовательские, должны иметь значение Name, не включающее префикс "Pset_".
Теперь нам надо связать через отношение IfcRelDefinesByProperties объект модели (т.е. зону) с набором пользовательских свойств:
#300003= IFCRELDEFINESBYPROPERTIES('1exRkosub2Lhx4KcKg$W0q',$,$,$,(#300000),#260010);
При создании отношения определяем значения 6 атрибутов:
  1. GlobalId
  2. OwnerHistory (optional)
  3. Name (optional)
  4. Description (optional)
  5. RelatedObjects
  6. RelatingPropertyDefinition
В RelatedObjects мы ссылаемся на строку, где указана зона (#300000), а в RelatingPropertyDefinition - на созданный набор свойств (#260010).
В итоге редактирования IFC-файла я добавил порядка 20 строк и создал 2 зоны со свойствами:
IFC-вьювер нам честно отобразил весь наш труд:
Вместо эпилога (посвящается тем, кто дочитал до конца).
То, что начиналось с задачи про зоны переросло в чтиво про структуру IFC.
Будете ли вы делать так же? Сомневаюсь. Полезно ли вам это было читать? Надеюсь, что да :) (напишите в комментариях свое мнение). 
Мы с вами узнали:
  1. Что внутри IFC-файл не такой страшный, как вам казалось это раньше :) и информация, которая там записана, прежде всего структурирована, что помогает человеку в ней разобраться.
  2. Что в IFC практически для всего есть свой класс и мы поняли с помощью каких IFC-классов описываются зоны и свойства для них.
  3. Что в IFC объекты могут быть связаны различными отношениями с помощью специальных классов и мы научились применять некоторые из них, например, объединять в одну группу.
Собственно и всё! Если интересно узнать ещё что-то про IFC - пишите вопросы… и возможно я (или мои коллеги) сможем на них ответить.
5 экспертов согласны
Очень интересные статьи. Спасибо!
Статья однозначно познавательная! Спасибо!
Но попробуйте прикинуть, сколько времени может занять, в доме квартир на 500, в ifc разнести помещения по зонам(квартирам). А потом после внесения изменений в проект, сделать это еще раз. 
Без полноценной сущности зона( квартира), это просто не выполнимая, за разумное время задача.