После появления упрощенного файла маппинга, который располагается по пути:

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 тоже выполнится после этой функции

Я думаю теперь вы примерно понимаете, что можно теперь сделать, насколько вообще можно автоматизировать передачу параметров, сколько вариаций вообще теперь существует.

Экспериментировать теперь можно совершенно по разному и с разными типами сущностей и элементами.