【问题标题】:How to get the bounding box from a Revit Element with Revit API, then call to center of that bounding box如何使用 Revit API 从 Revit Element 获取边界框,然后调用该边界框的中心
【发布时间】:2019-05-14 08:25:44
【问题描述】:

我正在尝试围绕其中心点旋转 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  

提前感谢您查看我目前所拥有的内容。如果有任何需要进一步澄清的地方,请告诉我!

编辑:

@CyrilWaechter

我认为你是对的。使用 LocationPoint 可能更有意义。我查看了您链接的脚本(谢谢!)并尝试在我的代码中实现此部分。

transform = doc.GetElement(picked.ElementId).GetTransform()

我通过此语句传递 ElementId,但出现错误,“Wall”对象没有属性“GetTransform”。你能帮我理解一下吗?

编辑 2: 感谢@JeremyTammik 和@CyrilWaechter,您的见解帮助我了解了哪里出了问题。虽然我仍然觉得 Revit API 中的某些属性不明确,但我能够让我的代码正确执行。我将在下面发布我能够工作的代码。

【问题讨论】:

  • 在你的情况下使用 LocationPoint 不是更有趣吗?就我而言,它几乎总是更好。您可能有兴趣查看my tool 及其source code
  • @CyrilWaechter 谢谢!你知道为什么我会收到我在编辑中列出的错误声明吗?
  • 因为如错误消息中所述。 GetTransform 方法do not exist for a Wall class。您是否尝试过在第 92 行使用 ElementTransformUtils ?
  • 感谢@CyrilWaechter 的帮助!我没有考虑将我选择的元素作为墙类的一部分。这让我走上了正确的道路!

标签: bounding-box revit-api revit revitpythonshell pyrevit


【解决方案1】:

边界框的中心很容易获得。 pickedReference。从中获取ElementId,使用doc.GetElement 打开它,并使用get_BoundingBox 检索边界框,参见。 Conduits Intersecting a Junction Box :

Element e = Util.SelectSingleElement(
  uidoc, "a junction box" );

BoundingBoxXYZ bb = e.get_BoundingBox( null );

对于某些元素和某些不规则形状,您可能希望使用质心而不是边界框:

【讨论】:

  • 你好杰里米!感谢您帮助我了解引用和 ElementID 之间的区别。我不知道这种区别。恐怕一旦有了 ElementID,我就不明白该怎么做。我会写一行代码说e = doc.GetElement(picked.ElementId)然后e_bb = e.BoundingBoxXYZ()吗?可能是我不理解的从 C# 到 Python 的转换。
  • 你列出的两行代码对我来说看起来很完美......你现在可能已经验证过了......
  • 感谢您的帮助@JeremyTammik,您的提示让我走上了正轨!
【解决方案2】:

以下是我使用 pyRevit 解决问题的方法。此代码允许您从边界框的中心绕其 Z 轴旋转元素。

要使用此代码,请选择一个 Revit 元素,然后打开 Revit Python Shell。将以下代码复制并粘贴到 Revit Python Shell 记事本中,然后单击运行按钮。这会将元素旋转 45 度,因为当前 rotateSelectedElement() 参数是 45。您可以在运行之前将此数字更改为任何值。

# Import the math module to convert user input degrees to radians.
import math

# Get a list of all user selected objects in the Revit Document.
selection = [doc.GetElement(x) for x in uidoc.Selection.GetElementIds()]

# Definitions
def rotateSelectedElement(degrees_to_rotate):
    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')

    # Convert the user input from degrees to radians.
    converted_value = float(degrees_to_rotate) * (math.pi / 180.0)

    # Begin new transaction
    t.Start()

    # Get the first selected element from the current Revit doc.
    el = selection[0].Id

    # 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()


# Execute    
# Add the desired degrees to rotate by as an argument for rotateSelectedElement()
rotateSelectedElement(45)

编辑:使代码更清晰。代码现在无需任何进一步修改即可在 Revit Python Shell 中执行。如果您遇到问题,请参考上面的说明!

【讨论】:

  • 恭喜您获得完整的解决方案,感谢您的分享。出于教学目的,我很乐意将此讨论添加到The Building Coder blog :-)
【解决方案3】:

The Building Coder 为后代编辑和保存:

非常感谢 Christian 的有趣讨论和 Cyril 提供的大量额外信息!

【讨论】:

  • 非常感谢 Jeremy 的这篇文章。这是太棒了。我已更新我的代码解决方案,无需任何进一步修改即可直接在 Revit Python Shell 中工作。我还添加了可以更好地解释代码的 cmets。您介意使用此最新解决方案更新您的博客文章吗?我觉得新的解决方案对有同样问题的人更有益。谢谢!
  • 没问题,来了...谢谢您的赞赏和新年快乐!
猜你喜欢
  • 2016-10-27
  • 2021-08-14
  • 2020-11-14
  • 1970-01-01
  • 2021-08-03
  • 1970-01-01
  • 2019-05-11
  • 2017-07-15
  • 2020-12-31
相关资源
最近更新 更多