Поступил запрос от клиента: иногда после разделения воздуховодов на отрезки приходится корректировать трассы, поэтому хорошо было бы убрать разделение, соединить их обратно. И после корректировок уже нарезать заново.
Я подумал: «Ну фигня-вопрос, щас за полчасика накидаю скрипт и отдам, как раз отвлекусь от рутины».
А в итоге это вылилось в полноценное изучение того, как Ревит строит и перестраивает воздуховоды. И заняло не полчаса, почти два рабочих дня.
Первая идея была простая и невинная: ищу в проекте все разделители по имени семейства и типа. У элементов получаю их соединители, а с соединителей разделителя получаю соединители воздуховодов, которые к нему подключены. Дальше по этим двум соединителя строю новый воздуховод. В Ревит АПИ есть такой метод.
В Ревите 2019 всё прекрасно работало, потому что до 2021 Ревита они там у себя внутри делали так, что при соединении воздуховоды сами объединяются. С 2021 версии это поведение исправили, якобы это вызывало проблемы при работе с рабочими наборами. Типа у одного воздуховода мог быть один затяный рабочий набор, у другого — другой, соответственно мог возникать конфликт.
Как по мне, это какой-то высосанный из пальца аргумент, ну да ладно. С 2021 Ревита воздуховоды при удалении элемента сами не объединяются и при добавлении нового кусочка тоже не срастаются в один воздуховод. В итоге у меня строились коротенькие кусочки, которые подключались к существующим воздуховодам. Ревит такое устраивает, а меня нет.
Вторая идея была — не строить кусок воздуховода, а удлинить существующие, а потом соединить их соединители. Тоже не сработало, получался разрыв, хоть воздуховоды и соединялись в сеть. Но мне-то надо объединить их в один.
В результате гугления понял, что никаких вариантов нет: надо удалять существующие воздуховоды и строить новый, иначе один воздуховод не получится. То есть по сути это мне надо вообще все прямики удалить и перестроить заново.
Ладно, так и сделал. Беру разделитель, получаю с него подключенные воздуховоды, а уже с них получаю элементы, которые подключены к воздуховодам. Дальше удаляю два эти воздуховода и разделитель, строю новый через точки на соседях удалённых воздуховодов. То есть, допустим, у нас есть разделитель, с двух сторон воздуховоды, а к ним подключены отводы. Вот между этими отводами и строю новый воздуховод.
Появилось две новые проблемы. Первая — врезки отсоединяются, что логично, ведь они подключались к тем воздуховодам, что я удалил, к новым они не подключаются сами по себе. Угадайте, что надо делать, если врезку надо подключить к воздуховоду? Правильно, только удалять и строить новую. Нельзя взять существующие и подключить к воздуховоду.
Акей, врезка строится методом, в котором надо дать соединитель элемента, от которого строим врезку, и воздуховод, из которого врезка выходит. Поэтому добавил ещё алгоритм, который берёт старую врезку, смотрит, что к ней подключено, запоминает, а потом заново подключает через врезку.
У воздуховода есть два вида соединителей — есть с типом End, конечные, и есть с типом Curve — это вот как раз точка на воздуховоде, куда подключается врезка. Скорее всего именно по координатам этой точки Ревит и понимает, как делить расходы до и после врезки в сети. Ведь при маркировке он правильно выводит расходы на воздуховодах с врезкой, хотя в параметрах воздуховода мы видим только суммарный расход.
Вторая проблема — некоторые воздуховоды, особенно вертикальные, стали проворачиваться. То есть идёт отвод вверх, Ревит считает, что его сечение 300х500, хотя даже визуально там 500х300. Ну и в итоге воздуховод он строит 300х500, хотя надо было 500х300.
Пришлось сначала методом проб и ошибок, а затем методом анализа выяснять какую-то зависимость между направлениями соединителей у воздуховодов и элементов, к которым они подключены. Для этого построил 8 комбинаций: воздуховод слева-направо, отвод в дальнюю сторону (от себя); воздуховод слева-направо, отвод в ближнюю сторону (к себе), то же вверх и вниз, потом справа-налево.
Всё для того, чтобы посмотреть ориентацию системы координат соединителей. У соединителей есть своя система координат, вы её можете видеть в семействах, когда выделяете соединитель. Там появляются координатные оси, причём ось Z всегда идёт вдоль оси подключения, а вот X и Y могут гулять.
Вот я и строил разные варианты, чтобы посмотреть, как сочетаются между собой координаты соединителей воздуховодов и подключенных к ним отводов. Построил, запустил скрипт, получил часть воздуховодов с проблемами, а часть без них. Сравнил и увидел, что во всех случаях с ошибкой оси Х соединителей были под углом 90°. Если угол был 0° или 180°, то проблем не возникало.
Добавил корректировку: если направления осей Х были равны 90°, то нужно повернуть элемент на 90°. Помогло, вертикальные и горизонтальные воздуховоды в тестовом файле стали строиться нормально.
Отдал клиенту очередную версию скрипта на тесты. Всё это получалось долго, сложно, с болью и унижениями, но я доволен, что всё же разобрался. Весьма вероятно, что эти знания мне пригодится где-будь в будущих скриптах. Я и так знал, что Ревит по сути каждый раз просто заново отстраивает сеть, но происходит это так быстро, что мы просто не замечаем этого, видно это только по смене Id элементов. Теперь вот и сам сделал то же самое, появилось больше понимания, как это происходит по капотом.