Как уменьшить размер step файла

Обновлено: 04.07.2024

Удивительная история приключилась на днях с конвертацией данных.

При чтении и последующей перезаписи произвольно взятой модели STEP-транслятором библиотеки OpenCascade, размер файла увеличился с 96 до 196 мегабайт. Изменение размера как таковое логично, поскольку данный файл не был произведен библиотекой OpenCascade (по всей видимости ядром являлся Parasolid), а в качестве конвертера выступали инструменты STEP Tools, но. Сто мегабайт сверху!

Выяснилось, что оригинальный STEP содержит

1,285 тыс. объектов, тогда как в перезаписаном файле объектов стало

2,248 тыс. Возникает вопрос: что это за дополнительный миллион (!) непрошенных сущностей?

Заметим, что перезапись того же файла в SolidWorks 2017 дала на выходе

1,903 объектов модели STEP, то есть наблюдаемый эффект не специфичен для OpenCascade.

Начнем с того, как узнать количество объектов в файле STEP. Для этого можно заглянуть непосредственно в файл (благо, он читабелен) и найти в нем самый старший идентификатор. Другой способ состоит в том, чтобы узнать количество объектов программно. Сделать это можно после чтения файла и перед его трансляцией в топологическую модель OpenCascade. Вот пример:

Обратите внимание на структуру данных StepData_StepModel. Она содержит объектную модель файла STEP как граф взаимосвязей между различными сущностями. В этой модели нет реальной геометрии CAD, а есть только ее описание, зеркалирующее состав оригинального файла. На следующем этапе содержимое StepData_StepModel будет интерпретироваться транслятором для воссоздания геометрической модели с ассоциированными метаданными.

После трансляции можно проверить состав CAD-модели "result" уже в терминах ее реально воссозданных граничных элементов.

Количество топологических объектов в оригинальном файле.

Существенной разницы между двумя файлами эта проверка не выявляет.

Количество топологических объектов в заново сохраненном файле.

Используя программный инструментарий, нетрудно собрать полную информацию о количестве и составе объектов STEP-модели еще до этапа трансляции. Ниже выведен дамп итоговой модели (той, которую «разнесло»):

Сличая такие дампы для исходного и результирующего файлов, можно заметить несколько интересных вещей. Вот только некоторые наблюдения:

  1. Исчезли объекты типа StepShape_VertexLoop.
  2. Все объекты StepShape_FaceOuterBound были преобразованы в StepShape_FaceBound.
  3. Количество нерациональных B-кривых (StepGeom_BSplineCurveWithKnots) возросло с 11743 до 15503.
  4. Количество точек в пространстве моделирования (StepGeom_CartesianPoint) возросло с 781,352 до 1,723,968 !
  5. И некоторые другие изменения.
Точки (StepGeom_CartesianPoint), прочитанные из оригинального STEP-файла.

В данном случае особенно подозрительным выглядит возросшее количество точек (StepGeom_CartesianPoint). Это может быть связано с тем, что какие-то точки, например, дублируются, либо, что менее очевидно, могла увеличиться сложность B-кривых и B-поверхностей. Например, вставка нового узла влечет образование дополнительной контрольной точки в B-кривой. В формате STEP это отразится возникновением новой сущности StepGeom_CartesianPoint вместе со ссылкой на нее из соответствующего определения B-кривой. Но пока это только догадки.

Начнем с проверки «в лоб». Для анализа пространственных точек на совпадение с контролируемой точностью можно использовать класс NCollection_CellFilter библиотеки OpenCascade. Для этого сначала реализуется собственно код проверки, например, вот так (обратите внимание на наследование от NCollection_CellFilter_InspectorXYZ):

Класс InspectXYZ описывает ячейку (cell) в пространстве с центром в некоторой точке "P" и зазором "tol". Метод Inspect() анализирует принятую извне точку на попадание в данную ячейку. Если расстояние между центром ячейки и данной точкой не превосходит значения зазора, то такие точки полагаются одинаковыми. На следующем этапе мы используем класс InspectXYZ для фильтрации точек:

Здесь asiAlgo_BaseCloud представляет собой облако точек, в которое добавляются только те тройки координат, что выдержали проверку фильтром. Используя эту технику, можно эффективно отсеивать геометрически близкие точки для решения разнообразных задач (например, аппроксимации). Управляя значением переменной "conf", мы контролируем степень разреженности облака. Поскольку в библиотеке OpenCascade совпадающими считаются точки, находящиеся друг от друга на расстоянии не более Precision::Confusion(), то будем использовать именно это значение (равное 1.e-7) для фильтрации. В результате получаем 669,750 точек, то есть более миллиона точек были отфильтрованы как совпадающие с другими. Итак, по всей видимости мы имеем дело с некоторой избыточностью объектов в модели STEP. Постараемся выяснить, а откуда данные точки вообще появились?

В оригинальном файле все B-кривые типа StepGeom_BSplineCurveWithKnots содержали 386,783 контрольных точек. В результирующем файле контрольных точек стало 1,326,619 , то есть на миллион больше.

Количество контрольных точек B-кривых до и после трансляции оригинального файла.

После трансляции CAD-модели, OpenCascade выполняет серию дополнительных действий для преобразования восстановленной геометрии в корректное состояние. Этот процесс необходим для преодоления различий, существующих между геометрическими ядрами. Хотя формат STEP сам по себе является «общим знаменателем» САПР, критерии, предъявляемые CAD-системами к геометрической модели, не вполне совпадают. Системы «разговаривают на разных языках». Технически, трансляция модели в OpenCascade венчается вызовом метода ProcessShape() класса XSAlgo_AlgoContainer.

Количество контрольных точек B-кривых после трансляции оригинального файла с выключенным постпроцессингом.

Класс XSAlgo_AlgoContainer выполняет, в частности, процедуры «лечения» модели, которые и приводят к повышению сложности геометрии. Отключать эти процедуры нельзя, так как в противном случае результирующая модель окажется непригодной к дальнейшей работе. Следует, однако, разобраться, что же не так с исходной моделью. Или «болеет» сам транслятор? Выясняется, что увеличение сложности ребер связано с работой класса ShapeFix_Face и его двух режимов:

Эти режимы позволяют вставить недостающие шовные ребра и соответствующим образом преобразовать контуры грани.

Одна из «больных» граней до обработки в ShapeFix_Face.

Согласно критериям корректности моделей в OpenCascade, любая грань должна иметь замкнутый контур в своем параметрическом пространстве. Шовное ребро — это ребро, проходящее через период несущей поверхности. В пространстве моделирования ему отвечает единственная кривая, тогда как в 2D оно имеет две сопряженные параметрические кривые. В исходном STEP-файле может не быть как самих шовных ребер (в силу особенностей геометрического ядра), так и параметрических кривых вообще. Восстановление этих недостающих объектов есть прямая обязанность пост-процессора OpenCascade.

Оказывается, что причиной появления миллиона новых точек является процесс восстановления шовного ребра. Шовное ребро разбивает существующие ребра на сегменты для образования новых контуров. Однако полученные сегменты переиспользуют в точности ту же несущую кривую, что и оригинальное ребро, претерпевающее разбиение. В результате там, где можно было обойтись лишь небольшим участком B-кривой, мы имеем ее полностью, со всеми контрольными точками и узловыми векторами.

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

Понятно, что копирование B-кривой означает, в частности, копирование ее контрольных точек. Именно поэтому мы и наблюдаем появление большого числа геометрически идентичных точек, которые, будучи записанными как отдельные объекты в STEP, дают заметное увеличение размера файла. В завершении отметим, что по результатам данного анализа был подготовлен отчет в официальный багтрекер. Давайте вместе делать ядро лучше.

Читайте также: