Создание перекрытия с отверстиями (продолжение)
Не так давно я обсуждал проблему программного создания перекрытия, которое имеет сложные границы, в частности имеет проемы.
Thorsten Meinecke из компании GTB - Berlin mbH предложил еще одну идею как можно создать такое перекрытие, используя BooleanOperationUtils.
Идея мне показалась интересной и я решил воплотить ее в жизнь. Тем более этот вариант предполагал именно создание перекрытие со сложными границами, а не создание отдельного проема в перекрытии, как это было реализовано в прошлый раз.
Алгоритм для копирования перекрытия со сложными границами:
1) Найти внешние границы исходного перекрытия
2) Создать новое перекрытие по внешней границе
3) Создать перекрытия по внутренним границам
4) Получить объемную форму (Solid) для нового перекрытия, созданного по внешней границе
5) Получить объемную форму (Solid) для перекрытий, созданных по внутренним границам.
6) Используя метод BooleanOperationsUtils.ExecuteBooleanOperationModifyingOriginalSolid изменить геометрию перекрытия, вычитав внутреннюю объемную форму из внешний
7) Удалить перекрытия, созданные по внутренним границам
Сначала находим внешние границы исходного перекрытия
Тут все просто.
Получаем объемную форму для перекрытия, находим верхнюю грань, берем ее границы. Первая граница и будет являться внешней границей перекрытия.
- var floorGeometry =
- floor.get_Geometry(new Options());
- var floorSolid =
- floorGeometry.First() as Solid;
- var topFace = SolidUtils.GetTopFace(floorSolid);
- var outerBoundary =
- topFace.EdgeLoops.get_Item(0);
Зная границу, просто создаем новое перекрытие с помощью метода NewFloor
Проверяем, есть ли у исходного перекрытия внутренние границы
- if (topFace.EdgeLoops.Size > 0)
Если есть, создаем перекрытия аналогично с помощью метода NewFloor
Далее я столкнулся с небольшой проблемкой. Прежде чем получить объемную фигуру созданного перекрытия, транзакция, в которой было перекрытие создано, должна быть обязательно подтверждена, иначе Revit просто не знает ничего о геометрии созданного объекта.
После того как я получил объемные фигуры созданных перекрытий, настало время воспользоваться операцией вычитания
- var newFloorSolid =
- newFloor.get_Geometry(new Options())
- .First() as Solid;
- foreach (var tempFloor in tempFloors)
- {
- var tempFloorSolid =
- tempFloor
- .get_Geometry(new Options())
- .First() as Solid;
- BooleanOperationsUtils
- .ExecuteBooleanOperationModifyingOriginalSolid(
- newFloorSolid,
- tempFloorSolid,
- BooleanOperationsType.Difference);
- }
Вот тут то меня и ожидал главный сюрприз. Такую операцию оказалось выполнить нельзя. Нельзя модифицировать объемную фигуру, которая была получена из 3D-объекта Revit.
The first solid object cannot be obtained directly from an element.
Жаль конечно. В теории это выглядело красиво.
Решил об этом написать, так как отрицательный результат, это тоже результат.
Наработки кода можно взять на GitHub.
Автор перевода: Виктор Чекалин
Обсуждение: http://adn-cis.org/forum/index.php?topic=234
Опубликовано 27.09.2013