После появления упрощенного файла маппинга, который располагается по пути:
C:\ProgramData\Topomatic\Robur Pipes\16.0\Support\ifc
Сам маппинг состоит из двух файлов форматов *.py и *.xml
- Файл формата *.xml является основным для редактирования, где параметры мы и "маппируем", он является основным файлом по преобразованию параметров.
- Файл формата .py является сопутствующим и нужен для запуска маппинга в Robur.
Мало кто знает, какую в себе силу хранит файл *.py, а ведь он может поменять полностью весь подход по передаче параметров в IFC.
Сначала определимся с целью, для чего нам это надо. Я буду разбирать ситуации на примере наружных инженерных сетей, подход вы поймете и сможете спроецировать его на другие виды работ и модули.
Давайте опишу ситуацию, нам надо передать информацию в трубу о типе системе, которой она принадлежит, делается это совершенно разными способами, я видел ситуации, когда от незнания, пользователи создавали целые библиотеки с одними и теми же элементами, которые распределяли на разные виды систем, одна и таже труба была в нескольких библиотеках и для электрики и для водопровода, что само по себе уже выглядит как не рабочим вариантом. В своей работе, я как специалист, который внедряет технологии информационного моделирования, придерживаюсь всегда одной логике, организовать работу так, что бы все работало на потоке. Все параметры должны приходить из программы, чтобы не преобразовывать их в других редакторах исключить человеческий фактор и сделать это максимально понятно и легко для обычного пользователя.
Можно назначать SMDX типы на протяженные трубы, задавать им параметры по типе системе, что довольно трудоемко. Давайте покажу, как можно передать параметр из линии сети в протяженный элемент или отметки, уклоны, тип прокладки из сегмента.

Откроем файл маппинга .py
После функции #возвращает значение описание свойства перечисления по ключу (Если у вас её нет, то внесите её, появилась в сборках от апреля 2026)
Мы сделаем дополнительные новые четыре функции
#1. Использовать когда свойство точно лежит в сегменте, а не выше
def get_from_segment(group, tag):
prop = get_property(find_owner(group), tag)
return prop.Value if prop else None
# 2. Использовать когда свойство точно лежит в сегменте, а не выше, значение берется по значению из списка соответствующему ключу
def get_enum_from_segment(group, tag):
prop = get_property(find_owner(group), tag)
return request_enum_value(prop) if prop else None
#3. Использовать когда свойство может лежать в сегменте или линии сети. Проверяет иерархию вверх до поиска нужного значения
def get_from_line(group, tag):
current = find_owner(group)
while current is not None:
prop = get_property(current, tag)
if prop is not None and prop.Value is not None:
return prop.Value
current = find_owner(current)
return None
#4. Использовать когда свойство может лежать в сегменте или линии сети. Проверяет иерархию вверх до поиска нужного значения с поиском значения по ключу
def get_enum_from_line(group, tag):
current = find_owner(group)
while current is not None:
prop = get_property(current, tag)
if prop is not None and prop.Value is not None:
return request_enum_value(prop)
current = find_owner(current)
return None
И получаем вот такой вид

Теперь, перейдем вниз и найдем функцию def process_custom(group) , она будет у вас пустая.
Будем использовать функцию flush и занесем в наши трубы информацию из линии сети и из сегмента
def process_custom(group):
if filter(group, "$type_4 = SmdxNetworksPipe"):
flush(group, [
# Группа параметров|Параметр # функция-источника # тэг свойства
["Экспертиза|Атрибут 1", get_enum_from_segment(group, "segment_layout_type")],
["Экспертиза|Атрибут 2", get_from_segment(group, "segment_end_cp_params.character_point_eg_dist")],
["Экспертиза|Атрибут 3", get_from_line(group, "line_network_type")],
])
return False
Рассказываю, что тут происходит, для "Атрибут 1" мы берез значение по tag "segment_layout_type" из списка значения. Почему из списка? списки в Robur представлены в виде Ключа и Значения (Key,Value) мы ищем соответствующее значение ключу, это можно увидеть в менеджере sdmx

"Атрибут 2" тут мы просто забираем значение из параметра "segment_end_cp_params.character_point_eg_dist"
Для тех кто не знает, параметр через точку берется, когда он находится внутри группы параметров
"Атрибут 3" забираем просто параметр не из списка для линии сети
Ну и как итог, после экспорта в IFC мы получаем нужные нам параметры из линии сети и сегментов для протяженных элементов

И синтаксис того, если надо сделать больше фильтров для разных видов
if filter(group, "$type_4 = SmdxNetworksPipe"):
flush(group, [
# IFC-атрибут # функция-источника # тэг свойства
["Экспертиза|Атрибут 1", get_enum_from_segment(group, "tag1")],
["Экспертиза|Атрибут 2", get_from_segment(group, "tag2)],
["Экспертиза|Атрибут 3", get_from_line (group, "tag3")]
])
if filter(group, "$type_4 = SmdxNetworksWire"):
flush(group, [
["Экспертиза|Атрибут 1", get_enum_from_segment(group, "tag1")],
["Экспертиза|Атрибут 2", get_from_segment (group, "tag2)],
["Экспертиза|Атрибут 3", get_from_line(group, "tag3")]
])
return Falsee
# return False — XML-маппинг из файла .xml тоже выполнится после этой функции
Я думаю теперь вы примерно понимаете, что можно теперь сделать, насколько вообще можно автоматизировать передачу параметров, сколько вариаций вообще теперь существует.
Экспериментировать теперь можно совершенно по разному и с разными типами сущностей и элементами.