Смещение элементов
В Revit API 2014 появилась довольно интересная возможность, позволяющая смещать элементы. В примерах, поставляемых вместе с Revit SDK есть замечательный пример, как можно использовать эту возможность для анимированной визуализации строительства (DisplacementElementAnimation).Интересно это смещение прежде всего тем, что элементы не смещаются физически в модели. Изменения видны лишь визуально и являются видозависимыми. Таким образом, сместив элементы на одном виде, на другом они останутся на своих местах.
Фактически же Revit создает новый элемент, называемый Набор смещаемых элементов (Displacement set) на заданном виде. Элементы, из которых был создан этот набор, скрываются.
Как это все работает.
Сначала, нам необходимо определить элементы, которые необходимо визуально сместить в другое место.
- List<ElementId> elementsToDisplace = new List<ElementId>();
- if (uidoc.Selection.Elements.Size == 0)
- {
- IList<Reference> references;
- try
- {
- references = uidoc.Selection.PickObjects(ObjectType.Element, "Select elements to displace");
- }
- catch (Autodesk.Revit.Exceptions.OperationCanceledException)
- {
- return Result.Cancelled;
- }
- foreach (var reference in references)
- {
- elementsToDisplace.Add(reference.ElementId);
- }
- }
- else
- {
- foreach (var elementId in uidoc.Selection.GetElementIds())
- {
- elementsToDisplace.Add(elementId);
- }
- }
Здесь, если в модели не выделен ни один элемент, то предлагается выделить нужные элементы.
Затем нужно определить направление и месторасположение, куда следует сместить элементы.
- XYZ displacement;
- try
- {
- displacement = uidoc.Selection.PickPoint("Select a point to move elements");
- }
- catch (Autodesk.Revit.Exceptions.OperationCanceledException)
- {
- var lastElement =
- doc.GetElement(elementsToDisplace.Last());
- if (lastElement.LevelId == ElementId.InvalidElementId)
- return Result.Cancelled;
- var level = doc.GetElement(lastElement.LevelId) as Level;
- displacement = new XYZ(0,0,level.Elevation+10);
- }
Предлагаем пользователю выбрать точку. Если он отменяет эту операцию, то смещаем элементы выше уровня последнего выделенного элемента.
Последним шагом мы создаем непосредственно новый смещаемый элемент.
- using (var t = new Transaction(doc, "Displace elements"))
- {
- t.Start();
- DisplacementElement displacementElement =
- DisplacementElement.Create(doc,
- elementsToDisplace,
- displacement,
- doc.ActiveView,
- null);
- t.Commit();
- }
Такое визуальное смещение возможно только в 3D-виде. Следует сделать дополнительную проверку, что активный вид является 3D-видом.
Результат представлен на рисунках.
Исходная модель:
Выделим парочку плит перекрытия и сместим их.
Физически же в модели плиты перекрытия остались на своем месте.
Выделив одну из смещенных плит, мы можем убедиться, что выделенные элементы являются не плитами, а набором смещаемых элементов.
Чтобы вернуть элементы на место, достаточно выделить набор смещенных элементов и удалить его.
Программно удалить все наборы смещаемых элементов можно с помощью вот такого кода
- using (var t = new Transaction(doc, "Delete displace elements"))
- {
- t.Start();
- var collector =
- new FilteredElementCollector(doc, doc.ActiveView.Id);
- var displaceElements =
- collector
- .OfClass(typeof (DisplacementElement))
- .ToElementIds();
- doc.Delete(displaceElements);
- t.Commit();
- }
Если не указывать идентификатор вида в конструкторе FilteredElementCollector, то удалятся все наборы во всем проекте.
Автор перевода: Виктор Чекалин
Обсуждение: http://adn-cis.org/forum/index.php?topic=229
Опубликовано 25.09.2013