При работе с 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. Дальнейшее развитие темы может включать:
- Работа с материалами вместо простых цветов, 
- Автоматизация стилизации на основе правил или фильтров. 
 
          