ADN Open CIS
Сообщество программистов Autodesk в СНГ

25/09/2013

Смещение элементов

В Revit API 2014 появилась довольно интересная возможность, позволяющая смещать элементы. В примерах, поставляемых вместе с Revit SDK есть замечательный пример, как можно использовать эту возможность для анимированной визуализации строительства (DisplacementElementAnimation).

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

Фактически же Revit создает новый элемент, называемый Набор смещаемых элементов (Displacement set) на заданном виде. Элементы, из которых был создан этот набор, скрываются.

Как это все работает.

Сначала, нам необходимо определить элементы, которые необходимо визуально сместить в другое место.

Код - C#: [Выделить]
  1.  
  2.             List<ElementId> elementsToDisplace = new List<ElementId>();
  3.  
  4.  
  5.             if (uidoc.Selection.Elements.Size == 0)
  6.             {
  7.                 IList<Reference> references;
  8.                 try
  9.                 {
  10.                     references = uidoc.Selection.PickObjects(ObjectType.Element, "Select elements to displace");
  11.                 }
  12.                 catch (Autodesk.Revit.Exceptions.OperationCanceledException)
  13.                 {
  14.                     return Result.Cancelled;
  15.  
  16.                 }
  17.  
  18.  
  19.                 foreach (var reference in references)
  20.                 {
  21.                     elementsToDisplace.Add(reference.ElementId);
  22.                 }
  23.             }
  24.             else
  25.             {
  26.                 foreach (var elementId in uidoc.Selection.GetElementIds())
  27.                 {
  28.                     elementsToDisplace.Add(elementId);
  29.                 }
  30.             }

Здесь, если в модели не выделен ни один элемент, то предлагается выделить нужные элементы.

Затем нужно определить направление и месторасположение, куда следует сместить элементы.

Код - C#: [Выделить]
  1.  
  2.             XYZ displacement;
  3.             try
  4.             {
  5.                 displacement = uidoc.Selection.PickPoint("Select a point to move elements");
  6.             }
  7.             catch (Autodesk.Revit.Exceptions.OperationCanceledException)
  8.             {
  9.                 var lastElement =
  10.                     doc.GetElement(elementsToDisplace.Last());
  11.                 if (lastElement.LevelId == ElementId.InvalidElementId)
  12.                     return Result.Cancelled;
  13.  
  14.                 var level = doc.GetElement(lastElement.LevelId) as Level;
  15.  
  16.                 displacement = new XYZ(0,0,level.Elevation+10);
  17.  
  18.             }

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

Последним шагом мы создаем непосредственно новый смещаемый элемент.

Код - C#: [Выделить]
  1.  
  2.             using (var t = new Transaction(doc, "Displace elements"))
  3.             {
  4.                 t.Start();
  5.  
  6.                 DisplacementElement displacementElement =
  7.                     DisplacementElement.Create(doc,
  8.                         elementsToDisplace,
  9.                         displacement,
  10.                         doc.ActiveView,
  11.                         null);
  12.  
  13.                 t.Commit();
  14.             }

Такое визуальное смещение возможно только в 3D-виде. Следует сделать дополнительную проверку, что активный вид является 3D-видом.

Результат представлен на рисунках.

Исходная модель:

 

Выделим парочку плит перекрытия и сместим их.

 

Физически же в модели плиты перекрытия остались на своем месте.

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

 

Чтобы вернуть элементы на место, достаточно выделить набор смещенных элементов и удалить его.

Программно удалить все наборы смещаемых элементов можно с помощью вот такого кода

Код - C#: [Выделить]
  1.  
  2.             using (var t = new Transaction(doc, "Delete displace elements"))
  3.             {
  4.                 t.Start();
  5.                 var collector =
  6.                     new FilteredElementCollector(doc, doc.ActiveView.Id);
  7.  
  8.                 var displaceElements =
  9.                     collector
  10.                         .OfClass(typeof (DisplacementElement))
  11.                         .ToElementIds();
  12.  
  13.                 doc.Delete(displaceElements);
  14.                 t.Commit();
  15.  
  16.             }

Если не указывать идентификатор вида в конструкторе FilteredElementCollector, то удалятся все наборы во всем проекте.

Автор: Виктор Чекалин
Автор перевода: Виктор Чекалин

Обсуждение: http://adn-cis.org/forum/index.php?topic=229

Опубликовано 25.09.2013