Python旋转拾取边界框中心
Python旋转拾取边界框中心
让我们从StackOverflow突出显示一个很好的交互式教学基于Python的Revit API学习挑战,由Christian Gentry在Cyril Waechter的帮助下进行更改,提出,讨论和解决,如何从Revit元素获取边界框并确定其中心:
西里尔的Python HVAC博客
您可以在下面看到为什么以下讨论也促使我查看Cyril非常好的Python HVAC博客。
用他自己的话说:
欢迎访问本网站,宣传并提供HVAC和BIM用途的脚本和应用程序。这些是用Python语言编写的。
当我开始我的职业生涯时,我希望我有很多节省时间的工具。许多人没有意识到只需几行代码即可节省多少时间。在我看来,所有可以自动化的应该是。人类在这里使用他的思想,而不是复制,粘贴和输入不需要任何大脑的数据。
为何选择Python?因为它是方便,互动,开源和跨平台。
Cyril的FAQ包含非常有用的信息和资源,用于开始使用pyRevit,Python和基础Revit API 的pyRevitMEP MEP扩展。
用Python在他们的中心周围旋转元素
问题:我正在尝试围绕其中心点旋转Revit元素。为此,我需要选择一个Revit元素并找到它的中心点,然后在该点创建一条坐标。
我最好的想法是将Revit元素包装在一个边界框中,然后找到该框的中心。我的问题是我不确定如何实现这一目标。
我正在使用pyRevit(神奇的工具),我仍然坚持如何使用边界框包装所选元素或检索其现有的边界框。
任何帮助将不胜感激!我真的想学习Revit API并理解一切是如何工作的。我正在取得进展,但有很多东西需要解压缩。
def pickobject(): from Autodesk.Revit.UI.Selection import ObjectType #define the active Revit application and document app = __revit__.Application doc = __revit__.ActiveUIDocument.Document uidoc = __revit__.ActiveUIDocument #define a transaction variable and describe the transaction t = Transaction(doc, 'This is my new transaction') # Begin new transaction t.Start() # Select an element in Revit picked = uidoc.Selection.PickObject(ObjectType.Element, "Select something.") ### ?????????? ### # Get bounding box of selected element. picked_bb = BoundingBoxXYZ(picked) # Get max and min points of bounding box. picked_bb_max = picked_bb.Max picked_bb_min = picked_bb.Min # Get center point between max and min points of bounding box. picked_bb_center = (picked_bb_max + picked_bb_min) / 2 ### ?????????? ### # Close the transaction t.Commit() return picked, picked_bb_center
提前感谢您看看我到目前为止所拥有的内容。
从Picked Reference中检索元素和边界框
边界框的中心很容易获得。 picked
是一个Reference
。ElementId
从中获取,使用打开它doc.GetElement
,然后使用get_BoundingBox
cf. 检索边界框。这个代码片段来自与交叉点相交的导管的讨论:
1 Element e = Util.SelectSingleElement( 2 uidoc, "a junction box" ); 3 4 BoundingBoxXYZ bb = e.get_BoundingBox( null );
对于某些元素和某些不规则形状,您可能希望使用质心而不是边界框:
使用位置点而不是边界框中心?
答:LocationPoint
在您的情况下使用它不是更有趣吗?就我而言,它几乎总是更好。您可能有兴趣看一下显示我的工具的两分钟视频,pyRevit的Revit API 3D旋转脚本及其源代码:
我在Python HVAC博客中关于脚本旋转元素的文章中详细描述了视频中显示的脚本。
回复:谢谢!
我想你是对的。使用LocationPoint
可能会更有意义。
我浏览了你链接的脚本(谢谢你!)并尝试在我的代码中实现这一部分:
1 transform = doc.GetElement(picked.ElementId).GetTransform()
我正在ElementId
通过这个声明,但是我得到一个错误,说该Wall
对象没有属性GetTransform
。你能帮我理解一下吗?
答案:因为,如错误消息中所述,该GetTransform
方法不存在于Wall
类实例中。
你试过用ElementTransformUtils
吗?
最终工作方案
这是我如何使用pyRevit解决我的问题。此代码允许您从其边界框的中心围绕其Z轴旋转元素。
def pickobject(): from Autodesk.Revit.UI.Selection import ObjectType #define the active Revit application and document app = __revit__.Application doc = __revit__.ActiveUIDocument.Document uidoc = __revit__.ActiveUIDocument #define a transaction variable and describe the transaction t = Transaction(doc, 'This is my new transaction') # Begin new transaction t.Start() # Select an element in Revit el = uidoc.Selection.PickObject(ObjectType.Element, "Select something.") # Get the element from the selected element reference el_ID = doc.GetElement(el) # Get the Bounding Box of the selected element. el_bb = el_ID.get_BoundingBox(doc.ActiveView) # Get the min and max values of the elements bounding box. el_bb_max = el_bb.Max el_bb_min = el_bb.Min # Get the center of the selected elements bounding box. el_bb_center = (el_bb_max + el_bb_min) / 2 #Create a line to use as a vector using the center location of the bounding box. p1 = XYZ(el_bb_center[0], el_bb_center[1], 0) p2 = XYZ(el_bb_center[0], el_bb_center[1], 1) myLine = Line.CreateBound(p1, p2) # Rotate the selected element. ElementTransformUtils.RotateElement(doc, el, myLine, converted_value) # Close the transaction t.Commit()
非常感谢Christian为有趣的讨论和Cyril提供了他提供的大量额外信息!
更新最终工作解决方案
寒假过后,克里斯蒂安补充道:
我已经更新了我的代码解决方案,无需进一步修改即可直接在Revit Python Shell中工作。我还添加了更好地解释代码的注释。您是否介意使用此最新解决方案更新您的博客文章?我觉得新解决方案对于同样问题的人更有利。谢谢!
这是我如何使用pyRevit解决我的问题。此代码允许您从其边界框的中心围绕其Z轴旋转元素。
要使用此代码,请选择单个Revit元素,然后打开Revit Python Shell。将下面的代码复制并粘贴到Revit Python Shell记事本中,然后单击“运行”按钮。这会将元素旋转45度,因为当前rotateSelectedElement
参数是45
。您可以在运行前将此数字更改为任何值。
1 # Import the math module to convert user input degrees to radians. 2 import math 3 4 # Get a list of all user selected objects in the Revit Document. 5 selection = [doc.GetElement(x) for x in uidoc.Selection.GetElementIds()] 6 7 # Definitions 8 def rotateSelectedElement(degrees_to_rotate): 9 from Autodesk.Revit.UI.Selection import ObjectType 10 11 #define the active Revit application and document 12 app = __revit__.Application 13 doc = __revit__.ActiveUIDocument.Document 14 uidoc = __revit__.ActiveUIDocument 15 16 #define a transaction variable and describe the transaction 17 t = Transaction(doc, 'This is my new transaction') 18 19 # Convert the user input from degrees to radians. 20 converted_value = float(degrees_to_rotate) * (math.pi / 180.0) 21 22 # Begin new transaction 23 t.Start() 24 25 # Get the first selected element from the current Revit doc. 26 el = selection[0].Id 27 28 # Get the element from the selected element reference 29 el_ID = doc.GetElement(el) 30 31 # Get the Bounding Box of the selected element. 32 el_bb = el_ID.get_BoundingBox(doc.ActiveView) 33 34 # Get the min and max values of the elements bounding box. 35 el_bb_max = el_bb.Max 36 el_bb_min = el_bb.Min 37 38 # Get the center of the selected elements bounding box. 39 el_bb_center = (el_bb_max + el_bb_min) / 2 40 41 #Create a line to use as a vector using the center location of the bounding box. 42 p1 = XYZ(el_bb_center[0], el_bb_center[1], 0) 43 p2 = XYZ(el_bb_center[0], el_bb_center[1], 1) 44 myLine = Line.CreateBound(p1, p2) 45 46 # Rotate the selected element. 47 ElementTransformUtils.RotateElement(doc, el, myLine, converted_value) 48 49 # Close the transaction 50 t.Commit() 51 52 53 # Execute 54 # Add the desired degrees to rotate by as an argument for rotateSelectedElement() 55 rotateSelectedElement(45)
Python流行度增长
根据经济学人和全球搜索引擎统计数据,谈到Python, Python正在成为世界上最流行的编码语言: