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

28/12/2018

Вращение элементов вокруг их оси с реализацией на Python

Вопрос: Я пытаюсь повернуть элементы Revit вокруг их центров. Для этого мне нужно выбрать элементы, найти из центры, затем построить линию с координатами этой точки.

Моя идея заключается в том, чтобы взять bounding box-ы элементов, найти их центры. Моя проблема в том, что я не уверен, как мне это сделать

Я использую pyRevit (отличная вещь!)  и я застрял - обернуть ли элемент в bounding box или получить существующие bounding box-ы.

Мой текущий прогресс:

Код - Python: [Выделить]
  1. def pickobject():
  2.                 from Autodesk.Revit.UI.Selection import ObjectType
  3.                
  4.                 app = __revit__.Application
  5.                 doc = __revit__.ActiveUIDocument.Document
  6.                 uidoc = __revit__.ActiveUIDocument
  7.                
  8.                 t = Transaction(doc, 'This is my new transaction')
  9.                
  10.                 t.Start()
  11.                
  12.                 picked = uidoc.Selection.PickObject(ObjectType.Element, "Select something.")
  13.                
  14.                 ### ?????????? ###
  15.                
  16.                 # Получить bounding box.
  17.                 picked_bb = BoundingBoxXYZ(picked) 
  18.                
  19.                 # Получить точки max и min bounding box-а.
  20.                 picked_bb_max = picked_bb.Max
  21.                 picked_bb_min = picked_bb.Min
  22.                
  23.                 # Получить центр bounding box-а.
  24.                 picked_bb_center = (picked_bb_max + picked_bb_min) / 2
  25.                
  26.                 ### ?????????? ###   
  27.                
  28.                 t.Commit()
  29.                
  30.                 return picked, picked_bb_center

Получить элемент и его Bounding Box из Reference-а

Ответ: Центр bounding box-а получить очень просто. Picked - это Reference. Получите Element используя метод doc.GetElement, а затем его bounding box:

Код - C#: [Выделить]
  1. Element e = Util.SelectSingleElement(uidoc, "Выбор элемента" );
  2.  
  3. BoundingBoxXYZ bb = e.get_BoundingBox( null );

Для некоторых элементов и неправильных форм, возможно лучшим решением будет получить центр тяжести (centroid) вместо bounding box-а:

- centroid твердотельной геометрии и расчет объемов

- GetCentroid на GitHub.

Использовать Location Point вместо центра Bounding Box?

Ответ: Быть может, в Вашем случае лучше использовать LocationPoint? В моём случае, это почти всегда лучше. Вот здесь Вы можете глянуть 2-минутное видео с демонстрацией работы моей утилиты, исходный код скрипта для pyRevit. Я описал работу скрипта, показанного в этом видео, в блоге есть статья о вращении элементов в любом направлении.

Ответ: Спасибо!

Я думаю, Вы правы насчет использования LocationPoint.

Я посмотрел Ваш скрипт (Спасибо ещё раз!) и попробовал реализовать в своем коде:

Код - Python: [Выделить]
  1. transform = doc.GetElement(picked.ElementId).GetTransform()

Я передаю Id элемента, но получаю ошибку, что объект Wall не имеет аттрибута GetTransform...

Ответ: Это потому что, как сказано в сообщении об ошибке Wall не имеет метода GetTransform. Вы пробовали использовать вместо этого ElementTransformUtils?

Готовое решение

Это мой финальный скрипт на pyRevit, позволяющий поворачивать элемент вокруг оси Z из центра его bounding box-а:

Код - Python: [Выделить]
  1. def pickobject():
  2.                 from Autodesk.Revit.UI.Selection import ObjectType
  3.  
  4.                 app = __revit__.Application
  5.                 doc = __revit__.ActiveUIDocument.Document
  6.                 uidoc = __revit__.ActiveUIDocument
  7.  
  8.                 t = Transaction(doc, 'This is my new transaction')
  9.  
  10.                 t.Start()
  11.  
  12.                 el = uidoc.Selection.PickObject(ObjectType.Element, "Select something.")
  13.  
  14.                 el_ID = doc.GetElement(el)     
  15.  
  16.                 el_bb = el_ID.get_BoundingBox(doc.ActiveView)
  17.  
  18.                 el_bb_max = el_bb.Max
  19.                 el_bb_min = el_bb.Min
  20.  
  21.                 el_bb_center = (el_bb_max + el_bb_min) / 2
  22.  
  23.                 p1 = XYZ(el_bb_center[0], el_bb_center[1], 0)
  24.                 p2 = XYZ(el_bb_center[0], el_bb_center[1], 1)
  25.                 myLine = Line.CreateBound(p1, p2)
  26.  
  27.                 ElementTransformUtils.RotateElement(doc, el, myLine, converted_value)
  28.  
  29.                 t.Commit()

 

Источник: https://thebuildingcoder.typepad.com/blog/2018/12/rotate-picked-element-around-bounding-box-centre-in-python.html#2

Автор перевода: Александр Игнатович

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

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