使用 Python 的新 Floor.Create() 方法 Revit 2023 API

New Floor.Create() method Revit 2023 APIs with Python

提问人:Angelo Massafra 提问时间:4/11/2023 更新时间:7/19/2023 访问量:406

问:

我目前正在通过pyRevit开发Revit插件,并且从Python中定义的三个顶点开始创建新的Revit三角形地板时遇到了一些麻烦。我是 Revit API 的新手,目前正在使用 Revit 2023。

我知道 API 与以前的版本相比有一些变化,例如新的 Floor.Create() 方法。但是,当我运行代码时,我收到错误消息“ArgumentException:输入曲线循环无法组成有效边界,这意味着:”curveLoops“集合为空;或者一些曲线环相互相交;或者每个曲线环不是单独闭合的;或者每个曲线环都不是平面的;或每个曲线环不在平行于水平面(XY)的平面上;或输入曲线包含至少一条螺旋曲线。参数名称:Autodesk.Revit..DB.Floor.Create(文档文档、IList'1 配置文件、ElementId floorTypeId、ElementId levelId)“中的配置文件。

经过进一步检查,我检查了 CurveLoop(),一切似乎都井井有条(它是平面的、闭合的和逆时针的)。我将不胜感激在解决此问题方面的任何帮助。

#! python3

#----------------------------------------------------------------------------------------------
# IMPORT LIBRARIES
#  System library
import sys

#  Autodesk Revit API
import clr
clr.AddReference('RevitAPI')
clr.AddReference('RevitAPIUI')
from Autodesk.Revit.DB import Transaction
from Autodesk.Revit.UI import TaskDialog
from Autodesk.Revit.DB import *
from Autodesk.Revit.DB import XYZ, UV, Line, CurveLoop, Level, Floor, FloorType
from System.Collections.Generic import List

# Function to convert centimeters to feet
def centimeters_to_feet(centimeters):
    return centimeters * 0.0328084

doc = __revit__.ActiveUIDocument.Document

# Coordinates
a = 0.0
b = 10.0
c = 0.0

# Input elevation (in centimeters)
elevation_cm = c
elevation_ft = centimeters_to_feet(elevation_cm)

# Create a new level at the given elevation
new_level = None

# Start a new transaction to modify the Revit document creating a new level
transaction = Transaction(doc, 'Create New Level')
transaction.Start()

try:
    new_level = Level.Create(doc, elevation_ft)
    
    # Assign a new name to the level
    new_level_name = "elBS_BuildingStorey_{:.0f}cm".format(elevation_cm)
    new_level.Name = new_level_name

    transaction.Commit()
except Exception as e:
    # If an error occurs, roll back the transaction and show an error message
    transaction.RollBack()
    TaskDialog.Show('Error', 'Failed to create level. Error: {}'.format(e))

if new_level:
    TaskDialog.Show('Success', 'Level created at elevation: {} centimeters'.format(elevation_cm))

# Create new floor

point0 = XYZ(a, a, c)
point1 = XYZ(b, a, c)
point2 = XYZ(b, b, c)

line01 = Line.CreateBound(point0,point1).ToRevitType()
line12= Line.CreateBound(point1,point2).ToRevitType()
line23 = Line.CreateBound(point2,point0).ToRevitType()

curveloop = CurveLoop()

curveloop.Append(line01)
curveloop.Append(line12)
curveloop.Append(line23)

print("numberOfcurves: ",curveloop.NumberOfCurves())
print("IsOpen: ",curveloop.IsOpen())
print("HasPlane: ",curveloop.HasPlane())


# Collect floor types
floortypes = FilteredElementCollector(doc).OfClass(FloorType)
floortypes = [f for f in floortypes]
floortypes_id = [f.Id for f in floortypes]
floortype_id = floortypes_id[0]
print("floortype id:",floortype_id)

# Collect building storeys
el_BuildingStoreys = FilteredElementCollector(doc).OfClass(Level)
el_BuildingStoreys_id = []
for el in el_BuildingStoreys:
    el_BuildingStoreys_id.append(el.Id)
level_id = el_BuildingStoreys_id[0]
print("level id: ",level_id)

# Start transaction
t = Transaction(doc, "Create new floor")
t.Start()

# Create the floor
new_floor = Floor.Create(doc, List[CurveLoop](curveloop), floortype_id, new_level.Id)
t.Commit()
Python Revit-API 地板 pyrevit

评论

0赞 Jeremy Tammik 4/11/2023
使用筛选元素收集器 FirstElementId 方法可以稍微缩短和简化代码。不过,我看不出是什么原因导致了这个问题。
0赞 Jeremy Tammik 4/11/2023
您是否查看过 Floor.Create 示例代码
0赞 Angelo Massafra 4/12/2023
@JeremyTammik非常感谢您的回复。我已经查看了示例代码。我尝试在Dynamo而不是pyRevit中运行Python代码,它可以工作,但我不明白为什么。因此,该问题仍然悬而未决,因为我需要在pyRevit中工作。
0赞 Jeremy Tammik 4/13/2023
很高兴听到它在 Revit API 和 Dynamo 中工作。不幸的是,我对pyRevit一无所知,所以我无法为您提供帮助。

答:

0赞 Diller 7/19/2023 #1

不确定这是否仍然相关,但是在使用pyRevit时,它使用的是IronPython而不是python。因此,在调用 Floor.Create() 方法时,您必须创建一个 C# 列表;

#create the floor
curveLoops = List[CurveLoop]()
curveLoops.Add(curveloop)

new_floor = Floor.Create(doc, curveLoops, floortype_id, new_level.Id)

从 IronPython 初始化 C# List<T>?

我对您的代码进行了更改并对其进行了测试,它对我有用。

在创建线条时,我还删除了 ToRevitType,这应该是不必要的。