Макрос для корректировки формы пространств

Автор Тема: Макрос для корректировки формы пространств  (Прочитано 8790 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн DinosaverАвтор темы

  • ADN OPEN
  • Сообщений: 4
  • Карма: 0
Коллеги, помогите новичку решить задачу на миллион:
Стандартный инструмент размещения пространств в Ревите создает их выдавливанием вдоль замкнутого контура стен. Как следствие - косяки при создании "пространств-в-пространстве" и т.п. - пространства (и помещения) не могут расширяться кверху, например.
НО.
При экспорте модели на обсчет в грин билдинг студио (и только в этом случае) ревит подправляет геометрию сложных пространств, используя алгоритм нахождения замкнутых объемов (а не контуров). Для этого в API есть класс BuildingEnvelopeAnalyzer - его методы реализуют этот алгоритм для нахождения наружных ограждающих конструкций и определения правильной конфигурации сложных пространств.
ЗАДАЧА
Заставить Ревит использовать этот алгоритм при размещении пространств прямо в ревите, а не во время экспорта в ГБС. Чтобы они прямо в Ревите были правильной (возможно, довольно сложной) формы.

Мне видится "просто" некий макрос, который запускается при размещении пользователем пространства. Этот макрос запускает алгоритм, который "пересоздает" пространство и делает его нужной формы.

Я потестил несколько конфигураций - при экспорте алгоритм отрабатывает все очень четко, модель получается аккуратная. Надо придумать, как запускать его изнутри - и миллионы инженеров будут вам благодарны...

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Dinosaver
Приветствую на форуме!
Надеюсь, если ответ на этот вопрос не будет найден в ближайшие дни, на него сможет ответить Виктор Чекалин после возвращения из отпуска.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Игнатович

  • Administrator
  • *****
  • Сообщений: 1152
  • Карма: 338
  • Skype: alexandr.ignatovich.itc
Dinosaver, правильно ли я понимаю, что эта задача нужна для расчетов правильных объемов?
И со сложными формами вопрос в том, что Revit считает площадь помещения или зоны и просто умножает её на высоту, заданную в свойствах помещения?

Ну здесь ситуация такая, что сложную геометрию в "высоту" напрямую для помещений и зон задать нельзя, однако, объемы посчитать можно попробовать. Думаю, что да, можно решить задачу с помощью BuildingEnvelopeAnalyzer, возможно, в сочетании со SpatialElementGeometryCalculator

Оффлайн DinosaverАвтор темы

  • ADN OPEN
  • Сообщений: 4
  • Карма: 0
Это нужно для правильных расчетов всего: неверное разбиение внутреннего объема приводит к неверным ассоциациям элементов: элементы, приходящиеся на "пустоты" не специфицируются нужным образом.
Вообще, чем больше думаю над этой задачей, тем больше вопросов. Главный из них: что такое пространство (или помещение) для Ревита? Creation класс содержит только 4 функции создания пространств: 2 для просто создания записей в базе (неразмещенные пространства) и 2 для создания пространств в модели, которые подхватывают замкнутые контуры стен на уровне, где пространства должны быть созданы (уровень идет как вход функций)... Все 4 - черный ящик. А что дальше?
Как пространство представлено и чем определяется в базе? Только точкой вставки? Нет. При работе с моделью вы видите границы именно геометрии пространств (на планах и разрезах). Или Ревит каждый раз при создании видов нечеловеческими усилиями пересчитывает эти границы, а потом еще и перелопачивает привязку всех элементов модели к пространствам?
В API есть масса методов для анализа, в т.ч. GeometryCalculator - отдельный класс для расчета границ помещений - но как указать собственные границы и насильно присвоить их пространству? А, главное, приведет ли это к переопределению формы пространства как ее видит Ревит?
С нетерпением жду вашей помощи.

Оффлайн Александр Игнатович

  • Administrator
  • *****
  • Сообщений: 1152
  • Карма: 338
  • Skype: alexandr.ignatovich.itc
Ну, во-первых, нужно понимать, что возможности API и то, что можно сделать через интерфейс Revit-а практически совпадают (да, есть небольшой набор функционала, доступный только программно, да, еще не все, что можно сделать руками доступно через API, но таких вещей все меньше с каждой новой версией Ревита)

Пространства, как и помещения для Revit-а некая абстракция, задаваемая уровнем (возможно со смещением), границами и высотой + набором специфических параметров (ну, кроме неразмещенных пространств/помещений, они есть в базе, но у них нет геометрии)

Уже созданные пространства/помещения редактируются только если изменяется что-то их ограничивающее, стены, либо за счет разделителей  пространств/помещений, в самом классе Space методов редактирования пространства нет:

Space.Level / Space.LevelId - уровень
Space.GetBoundarySegments - получить границы
Space.UnboundedHeight - высота
Ну формально, есть еще точка вставки Location - нужно привести к LocationPoint, но вряд ли она сильно интересна
Еще есть геометрия (просто поднимаем "выдавливание" от границ на высоту пространства/помещения), получаем Solid, который можно при желании можно получить и анализировать.

Теперь по поводу создания пространств:
public Space NewSpace(Phase phase) - создает неразмещенное пространство

public Space NewSpace(Level level, UV point) - указываем уровень и точку на плоскости, которая будет принадлежать пространству. Получаем Autodesk.Revit.Exceptions.InvalidOperationException, если пространство создать нельзя

public Space NewSpace( Level level, Phase phase, UV point ) - аналогично предыдущему, только еще указываем стадию

public ModelCurveArray NewSpaceBoundaryLines( SketchPlane sketchPlane, CurveArray curves, View view ) - а вот это для создания разделителей пространств

Public method NewSpaces2(Phase, Int32) - создаем сразу n неразмещенных пространств

Public method NewSpaces2(Level, Phase, View) - создаем пачку пространств (по замкнутым контурам) на уровне Level

С помещениями вроде бы методы похожие

Ну и да, если изменяются границы или добавляются разделители, сами пространства/помещения изменяются, но это все только в плане, на разрезе высота неизменна.

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

И да, еще в SDK есть пример AddSpaceAndZone, гляньте его

Оффлайн DinosaverАвтор темы

  • ADN OPEN
  • Сообщений: 4
  • Карма: 0
Спасибо, но я все это просмотрел и так и не нашел ответ на вопрос: можно ли вручную изменить геометрию пространства (помещения), приписав ему границы замкнутого объема? Пока я вижу (и Вы это подробно описали выше) только те же методы, что и в UI - разделители, изменения высот и замкнутого контура стен, видимого из точки вставки. Это не то - надо залезть в само определение пространства в базе, я подозреваю. Если это нельзя сделать - нет так нет.

Оффлайн Александр Игнатович

  • Administrator
  • *****
  • Сообщений: 1152
  • Карма: 338
  • Skype: alexandr.ignatovich.itc
Так я ж писал, что
если изменяются границы или добавляются разделители, сами пространства/помещения изменяются, но это все только в плане, на разрезе высота неизменна.
, соответственно, стандартными средствами так сделать нельзя, но это не значит, что изначальные задачи по специфицированию, подсчету объемов и т.д. не решаемы :-)

Оффлайн DinosaverАвтор темы

  • ADN OPEN
  • Сообщений: 4
  • Карма: 0
В итоге: как переписать границы помещения из конкретного набора элементов, id которых известен?

Оффлайн Александр Игнатович

  • Administrator
  • *****
  • Сообщений: 1152
  • Карма: 338
  • Skype: alexandr.ignatovich.itc
Еще раз, границы помещения переписать можно только так, как это можно сделать через UI самого Revit-а.

Но можно посчитать, например, объем помещения, определить элементы, относящиеся к нему, как-то примерно вот так: с помощью BuildingEnvelopeAnalyzer определить элементы, ограничивающие объем, получить их поверхности, построить по ним DirectShape, получить его Solid, взять его объем, с помощью ElementIntersectsFilter определить элементы, находящиеся в данном объеме.