«Давай покрасим холодильник в черный цвет»
При работе с BIM-моделями в формате IFC важно не только управлять геометрией и структурой здания, но и визуальными аспектами — например, цветами элементов. Цвет в IFC используется для улучшения читаемости моделей, визуализации этапов строительства, указания состояний (демонтаж, новое строительство и т.д.) или просто для улучшения презентации.
В этой статье мы разберём, как с помощью Python и библиотеки IfcOpenShell изменить цвет у конкретной стены в IFC-модели. Вы узнаете:
как устроено цветовое оформление в структуре IFC,
как найти нужную геометрию элемента и назначить ей новый цвет.
Фрагмент кода IFC-модели, который будем рассматривать:
#38=IFCINDEXEDPOLYCURVE(#37,$,.F.);
#39=IFCSHAPEREPRESENTATION(#23,'Axis','Curve3D',(#38));
#40=IFCSIUNIT(*,.AREAUNIT.,$,.SQUARE_METRE.);
#41=IFCCARTESIANPOINTLIST2D(((1.0,0.1),(0.0,0.1),(0.0,-0.1),(1.0,-0.1),(1.0,0.1)));
#42=IFCINDEXEDPOLYCURVE(#41,$,.F.);
#43=IFCARBITRARYCLOSEDPROFILEDEF(.AREA.,$,#42);
#44=IFCAXIS2PLACEMENT3D(#3,$,$);
#45=IFCEXTRUDEDAREASOLID(#43,#44,#9,3.0);
#46=IFCCOLOURRGB($,0.4,0.4,0.4);
#47=IFCSURFACESTYLERENDERING(#46,0.,$,$,$,$,IFCNORMALISEDRATIOMEASURE(0.5),IFCSPECULAREXPONENT(64.),.NOTDEFINED.);
#48=IFCSURFACESTYLE('BETON',.BOTH.,(#47));
#49=IFCSTYLEDITEM(#45,(#48),$);
#50=IFCSHAPEREPRESENTATION(#24,'Body','SweptSolid',(#45));
#51=IFCPRODUCTDEFINITIONSHAPE($,$,(#39,#50));
#52=IFCWALL('0VzfWMtfn4JPwrOjwyw8oL',#18,'W01',$,$,#36,#51,'2512159',$);
Чтобы проще следить за ходом назначения цвета для геометрии стены, будем читать этот фрагмент от конца к началу.
Геометрия
#52
это элемент класса IfcWall
. Другими словами, данный элемент модели — стена с именем 'W01'
. Стены по своей сути — это не геометрические фигуры, а объекты строительства, которые имеют некую форму. Поэтому просто изменить цвет стены мы не можем. Какая же форма у нашей стены? В самой стене указано, что её форма определена в строке с id #51
. Следовательно, поднимаемся на строку выше.
#51
Класс IfcProductDefinitionShape
определяет форму (геометрию) для любого объекта, который является подклассом IfcProduct
, например IfcWall
, IfcColumn
, IfcDoor
и др. В нашем случае форма определяется двумя вещами:
#39
— тут нам особо делать нечего, ведь это просто ось стены, которая создана классомIfcShapeRepresentation
с атрибутом'Axis'
.#50
— здестьIfcShapeRepresentation
уже с'Body'
. Как раз то, что нам надо. Так описывается твёрдотельная форма. Само же твёрдое тело, т.е. Солид, создано в#45.
#45
Класс IfcExtrudedAreaSolid
описывает трехмерное тело, созданное путем выдавливания (экструзии) 2D-профиля.
Итак, мы добрались до нужной нам геометрии. Мы хотим придать ей другой цвет. Будем проводить манипуляции с солидом в строке с id #45
. Теперь посмотрим, как устроен цвет.
Цвет
В данном случае мы так же пойдём от конца к началу. Так сможем точнее представить процесс создания стиля.
В строке #48
указан стиль поверхности. Стиль визуального отображения поверхности задаётся задаётся классом IfcSurfaceStyle
и имеет следующие атрибуты:
'BETON'
– Имя стиля..BOTH.
– Определяет, к каким сторонам поверхности применяется стиль. В данном случае ко всем.#47
– Ссылка на стиль рендеринга, который содержит конкретные параметры отображения (цвет, прозрачность, отражение и т.д.). Идём сюда.
#47
Класс IfcSurfaceStyleRendering
описывает параметры стиля, то есть как именно в IFC-модели будеть выглядеть поверхность. Описание включает цвет (#46
), прозрачность (от 0 = полностью непрозрачная до 1 = полностью прозрачная), отражательная способность 0.5 и другие свойства визуализации.
Итак, в #46
мы нашли информацию о цвете. Это строка с классом IfcColourRgb
. Имя у цвета не задано, поэтому стоит $
. Остальные атрибуты цвета это (Red, Green, Blue). В нашем случае 0.4,0.4,0.4 означает 40% каждого цвета. Так получается серый цвет средней насыщенности.
Примеры других цветов в IFC:
Совет
Для материалов старайтесь избегать чистых RGB (например, (1.0, 0.0, 0.0) или (0.0, 0.0, 1.0)). Лучше использовать приглушенные тона с небольшими вариациями каналов. Тогда они выглядят естественнее.
1. Глубокие природные оттенки
Темно-бирюзовый
IFCCOLOURRGB($, 0.0, 0.5, 0.5);
(Как океанская вода)Оливковый
IFCCOLOURRGB($, 0.5, 0.5, 0.0);
(Землистый и натуральный)Терракота
IFCCOLOURRGB($, 0.8, 0.4, 0.3);
(Теплый керамический оттенок)
2. Яркие акцентные цвета
Неоново-розовый
IFCCOLOURRGB($, 1.0, 0.2, 0.6);
(Для выделения важных элементов)Электрический синий
IFCCOLOURRGB($, 0.0, 0.7, 1.0);
(Современный и технологичный)Ярко-лаймовый
IFCCOLOURRGB($, 0.6, 1.0, 0.2);
(Для зон безопасности или динамичных объектов)
3. Сложные и элегантные тона
Бордовый
IFCCOLOURRGB($, 0.5, 0.0, 0.2);
(Подходит для интерьеров премиум-класса)Золотистый
IFCCOLOURRGB($, 0.9, 0.8, 0.1);
(Имитация металла или декора)Глубокий фиолетовый
IFCCOLOURRGB($, 0.4, 0.1, 0.6);
(Для креативных пространств)
Цветная геометрия
Внимательный читатель наверняка заметил, что поднимаясь по списку снизу вверх мы перескочили строку #49
, в которой содержится класс IfcStyledItem
.
В IFC-модели данный класс определяет применение стиля визуализации к конкретному геометрическому объекту. Это связующее звено между геометрией и её внешним видом.
Как это работает в IFC-модели?
#45
определяет геометрию (например, форму нашей стены),#48
определяет то, как эта геометрия должна выглядеть (стиль "BETON"),#49
связывает их вместе.
Таким образом, если в строке #46=IFCCOLOURRGB($,0.4,0.4,0.4)
; мы заменим комбинацию RGB c 0.4,0.4,0.4 на 0.6, 1.0, 0.2, т.е. сделаем #46=IFCCOLOURRGB($,0.6, 1.0, 0.2)
, то все геометрические элементы модели, которые используют стиль из строки #48 окрасятся в цвет лайма.
Эх, жаль, что нас сейчас не видят алхимики, ведь мы только что исполнили их давнюю мечту — превратили серый камень в золото.
Один геометрический объект может иметь несколько стилей через запятую в круглых скобках: (#48,#..,#..)
. В сложных случаях можно назначать разные стили разным частям объекта.
Это была теория. Теперь давайте применим наш филосовский камень для чего-то более практичного. Насвистывая мотив Нино Рота напишем код на Python с использованием библиотеки IfcOpenShell
, который будет изменять цвет только тех стен, которые называются 'W01' или 'W03'
. Поехали...
Давай покрасим холодильник в чёрный цвет.
Он белым был, он серым был, а чёрным – нет…
Модификация стен в Python
1. Подготовка
Импортируется библиотека
IfcOpenShell
для работы с IFC.Указывается путь к IFC-файлу.
Файл открывается и загружается в переменную
model.
Указываются имена стен, у которых нужно изменить цвета. Здесь это
'W01'
и'W03'.
import ifcopenshell
ifc_file_path = r'D:\IFC\Projekt2.ifc' # Замените на ваш путь к файлу модели
model = ifcopenshell.open(ifc_file_path)
wall_names = ['W01','W03']
2. Создание нового стиля
Создается цвет RGB (1.0, 0.2, 0.6) - ярко-розовый,
Создается стиль рендеринга с указанным цветом:
Прозрачность 0.0 (непрозрачный),
Остальные параметры (отражение и т.д.) не заданы.
Создается стиль поверхности с именем "NEW_COLOR":
Применяется к обеим сторонам поверхности ("BOTH"),
Используется созданный ранее стиль рендеринга.
На каждом этапе проверяется успешность создания.
try:
#2.1 Создание розового цвета
color = model.create_entity("IFCCOLOURRGB", None, 1.0, 0.2, 0.6) #Розовый
if not color:
raise ValueError("Ошибка: IFCCOLOURRGB не создан")
#2.2 Создание параметров рендеринга
rendering = model.create_entity("IFCSURFACESTYLERENDERING",
color, 0.0, None, None, None, None, None, None, "NOTDEFINED")
if not rendering:
raise ValueError("Ошибка: IFCSURFACESTYLERENDERING не создан")
#2.3 Создание стиля поверхности
surface_style = model.create_entity("IFCSURFACESTYLE", "NEW_COLOR", "BOTH", [rendering])
if not surface_style:
raise ValueError("Ошибка: IFCSURFACESTYLE не создан")
print(f"Создан новый стиль с ID: {surface_style.id()}")
except Exception as e:
print(f"Произошла ошибка: {e}")
3. Добавление созданных сущностей (цвет, рендеринг, стиль) в IFC-модель
Новые сущности добавляются в модель.
В коде IFC-Модели новые строки с цветом, рендерингом и стилем записываются в конец.
model.add(color)
model.add(rendering)
model.add(surface_style)
4. Создание списка стен для модификации и применение к ним нового стиля
Создается список стен с именами
'W01'
и'W03'
.Для каждой найденной стены:
Проверяется наличие геометрии.
Из всей геометрии оставляем только твердотельные элементы. Оси стен исключаем.
Для каждого твердотельного элемента геометрии находится стиль его внешнего вида.
Заменяется стиль на новый (розовый).
walls = [wall for wall in model.by_type("IFCWALL") if wall.Name in ['W01','W03']]
new_style = surface_style
for wall in walls:
if wall.Representation:
for shape_rep in wall.Representation.Representations:
if shape_rep.RepresentationType == "SweptSolid":
for item in shape_rep.Items:
solid_id = item.id()
for style_item in model.by_type("IFCSTYLEDITEM"):
if style_item.Item.id() == solid_id:
style_item.Styles = [new_style]
print(f"К солиду стены {wall.Name} применен стиль с ID {surface_style.id()}")
5. Сохранение изменений в IFC-Модели
Измененная модель сохраняется обратно в тот же файл.
model.write(ifc_file_path)
Примечание
В IFC-Модели из статьи использованы имена на латинице. Если вы решите повторить тоже самое со стенами, названными на кириллице, например 'Стена01'
, то получите ошибку. Дело в том, что для символов кириллицы IFC и STEP-формат используют символы BMP (Basic Multilingual Plane). Слова на кириллице передаются последовательностями вида '/X2/коды символов кириллицы/X0/'
Таким образом, слово'Стена01'
в этой кодировке будет выглядеть как '\X2\042104420435043D0430\X0\01'.
Запуск скрипта
Скрипт
#1. Подготовка
import ifcopenshell
ifc_file_path = r'D:\IFC\Projekt2.ifc' # Замените на ваш путь
model = ifcopenshell.open(ifc_file_path)
wall_names = ['W01','W03']
#2. Создание нового стиля
try:
#2.1 Создание розового цвета
color = model.create_entity("IFCCOLOURRGB", None, 1.0, 0.2, 0.6) #Розовый
if not color:
raise ValueError("Ошибка: IFCCOLOURRGB не создан")
#2.2 Создание параметров рендеринга
rendering = model.create_entity("IFCSURFACESTYLERENDERING",
color, 0.0, None, None, None, None, None, None, "NOTDEFINED")
if not rendering:
raise ValueError("Ошибка: IFCSURFACESTYLERENDERING не создан")
#2.3 Создание стиля поверхности
surface_style = model.create_entity("IFCSURFACESTYLE", "NEW_COLOR", "BOTH", [rendering])
if not surface_style:
raise ValueError("Ошибка: IFCSURFACESTYLE не создан")
print(f"Создан новый стиль с ID: {surface_style.id()}")
except Exception as e:
print(f"Произошла ошибка: {e}")
# 3. Добавление созданных сущностей (цвет, рендеринг, стиль) в IFC-модель
model.add(color)
model.add(rendering)
model.add(surface_style)
# 4. Создание списка стен для модификации и применение к ним нового стиля
walls = [wall for wall in model.by_type("IFCWALL") if wall.Name in wall_names]
new_style = surface_style
for wall in walls:
if wall.Representation:
for shape_rep in wall.Representation.Representations:
if shape_rep.RepresentationType == "SweptSolid":
for item in shape_rep.Items:
solid_id = item.id()
for style_item in model.by_type("IFCSTYLEDITEM"):
if style_item.Item.id() == solid_id:
style_item.Styles = [new_style]
print(f"К солиду стены {wall.Name} применен стиль с ID {surface_style.id()}")
# 5. Сохранение изменений в IFC-Модели
model.write(ifc_file_path)
Если в качестве IFC-вьювера вы используете Blender, то скрипт можно запустить прямо в нём.
Скопируйте вышеприведенный код скрипта Python сначала в блокнот. Возможно, это поможет избежать проблем с отступами, которые, как известно, критичны для Python. Затем в Blender откройте владку Scripting (1) и в окно (2) вставьте сразу весь код (ctrl+V). При необходимости после вставки нажимайте Enter.
Установка IfcOpenShell для использования в Blender
Если вы планируете использовать библиотеку IfcOpenShell в Blender, то нужно обновить/установить эту библиотеку. В командной строке запустим команду "C:\Program Files\Blender Foundation\Blender 4.2\4.2\python\bin\python.exe" -m pip install --upgrade ifcopenshell
Обратите внимание на версию и расположение Blender на вашем компьютере.
Команды для командной строки чтобы удалить, установить или обновить IfcOpenShell:
pip uninstall ifcopenshell
pip install ifcopenshell
pip install --upgrade ifcopenshell
Итоговый эффект
Скрипт находит в модели стены с именами 'W01'
и 'W03'
и изменяет их цвет на ярко-розовый. При этом сохраняются все остальные параметры (геометрия, свойства и т.д.). Все изменения записываются обратно в исходный файл.
Заключение
В данной статье был рассмотрен практический пример изменения визуального стиля стен в IFC-файле через:
Создание нового цвета (IFCCOLOURRGB),
Определение параметров рендеринга (IFCSURFACESTYLERENDERING),
Формирование стиля поверхности (IFCSURFACESTYLE),
Применение стиля к конкретным геометрическим объектам (IFCSTYLEDITEM).
Важно отметить, что в стандарте IFC предусмотрено несколько альтернативных подходов к заданию визуальных свойств элементов модели.
Для различных типов объектов, таких как мебель, окна и двери, инженерные системы или несущие конструкции, могут применяться отличающиеся механизмы стилизации. Цвет может задаваться не только с помощью IFCCOLOURRGB
, но также через:
Материалы (
IFCMATERIAL
),Текстуры (
IFCIMAGETEXTURE
).
В более сложных случаях используются методы стилизации по классам объектов или правила условного отображения (rule-based visualization). Это не стандартизировано в IFC напрямую, но активно используется в приложениях, таких как Solibri, BIMcollab Zoom, Revit, Navisworks и др.
Метод, рассмотренный в этой статье, подходит для точечного изменения отдельных элементов. Однако, в профессиональной практике чаще применяются более масштабируемые подходы:
Централизованные таблицы стилей,
Привязка к классификаторам (например, КСИ, OmniClass, UniClass),
Системы управления визуальными свойствами на уровне всей модели.
Итак, мы подняли несколько важных аспектов, которые, возможно, будут полезны читателю с техническим интересом или профессиональным опытом в BIM. Дальнейшее развитие темы может включать:
Работа с материалами вместо простых цветов,
Автоматизация стилизации на основе правил или фильтров.