Revit API/Dynamo 脚本中的 MullionType 错误
MullionType errors in Revit API/Dynamo script
我正在编写一个 Python 脚本,该脚本接受一组输入线并将竖框分配给它们相交的相应网格线。但是,我收到一个奇怪的错误:
我不知道如何在脚本结尾处更正。 Python 告诉我它需要一个 MullionType 并得到一个 Family Type(见图)。我使用的是 Spring 节点的 Collector.WallTypes 的修改版本,它收集竖梃类型,但节点的输出是脚本不接受的族类型。知道如何让 Mullion Type 进入最终的 Python 节点吗?
Spring节点脚本:
#Copyright(c) 2016, Dimitar Venkov
# @5devene, dimitar.ven@gmail.com
import clr
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
doc = DocumentManager.Instance.CurrentDBDocument
clr.AddReference("RevitAPI")
from Autodesk.Revit.DB import *
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
def tolist(obj1):
if hasattr(obj1,"__iter__"): return obj1
else: return [obj1]
fn = tolist(IN[0])
fn = [str(n) for n in fn]
result, similar, names = [], [], []
fec = FilteredElementCollector(doc).OfClass(MullionType)
for i in fec:
n1 = Element.Name.__get__(i)
names.append(n1)
if any(fn1 == n1 for fn1 in fn):
result.append(i.ToDSType(True))
elif any(fn1.lower() in n1.lower() for fn1 in fn):
similar.append(i.ToDSType(True))
if len(result) > 0:
OUT = result,similar
if len(result) == 0 and len(similar) > 0:
OUT = "No exact match found. Check partial below:",similar
if len(result) == 0 and len(similar) == 0:
OUT = "No match found! Check names below:", names
SpringNodes 脚本输出族类型,即使收集器用于竖梃类型(见上图)
这是我的脚本:
import clr
# Import RevitAPI
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *
# Import DocumentManager and TransactionManager
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
# Import ToDSType(bool) extension method
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.GeometryConversion)
from System import Array
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
import math
doc = DocumentManager.Instance.CurrentDBDocument
app = DocumentManager.Instance.CurrentUIApplication.Application
walls = UnwrapElement(IN[0])
toggle = IN[1]
inputLine = IN[2]
mullionType = IN[3]
wallSrf = []
heights = []
finalPoints = []
directions = []
isPrimary = []
projectedCrvs = []
keySegments = []
keySegmentsGeom = []
gridSegments = []
gridSegmentsGeom = []
gridLines = []
gridLinesGeom = []
keyGridLines = []
keyGridLinesGeom = []
projectedGridlines = []
lineDirections = []
gridLineDirection = []
allTrueFalse = []
if toggle == True:
TransactionManager.Instance.EnsureInTransaction(doc)
for w, g in zip(walls,inputLine):
pointCoords = []
primary = []
## Get curtain wall element sketch line
originLine = Revit.GeometryConversion.RevitToProtoCurve.ToProtoType( w.Location.Curve, True )
originLineLength = w.Location.Curve.ApproximateLength
## Get curtain wall element height, loft to create surface
for p in w.Parameters:
if p.Definition.Name == 'Unconnected Height':
height = p.AsDouble()
topLine = originLine.Translate(0,0,height)
srfCurves = [originLine,topLine]
wallSrf = NurbsSurface.ByLoft(srfCurves)
## Get centerpoint of curve, determine whether it extends across entire gridline
projectedCrvCenterpoint = []
for d in g:
lineDirection = d.Direction.Normalized()
lineDirections.append(lineDirection)
curveProject= d.PullOntoSurface(wallSrf)
if abs(lineDirection.Z) == 1:
if curveProject.Length >= height-.5:
primary.append(False)
else:
primary.append(True)
else:
if curveProject.Length >= originLineLength-.5:
primary.append(False)
else:
primary.append(True)
centerPoint = curveProject.PointAtParameter(0.5)
pointList = []
projectedCrvCenterpoint.append(centerPoint)
## Project centerpoint of curve onto wall surface
for h in [centerPoint]:
pointUnwrap = UnwrapElement(centerPoint)
pointList.append(pointUnwrap.X)
pointList.append(pointUnwrap.Y)
pointList.append(pointUnwrap.Z)
pointCoords.append(pointList)
finalPoints.append(pointCoords)
isPrimary.append(primary)
projectedCrvs.append(projectedCrvCenterpoint)
TransactionManager.Instance.TransactionTaskDone()
TransactionManager.Instance.EnsureInTransaction(doc)
##Gather all segments of gridline geometry
for wall in UnwrapElement(walls):
gridSegments2 = []
gridSegmentsGeom2 = []
gridLines1 = []
gridLinesGeom1 = []
for id1 in wall.CurtainGrid.GetVGridLineIds():
gridLinesGeom1.append(Revit.GeometryConversion.RevitToProtoCurve.ToProtoType(doc.GetElement(id1).FullCurve))
gridLines1.append(doc.GetElement(id1))
VgridSegments1 = []
VgridSegmentsGeom1 = []
for i in doc.GetElement(id1).AllSegmentCurves:
VgridSegments1.append(i)
VgridSegmentsGeom1.append(Revit.GeometryConversion.RevitToProtoCurve.ToProtoType(i,True))
gridSegments2.append(VgridSegments1)
gridSegmentsGeom2.append(VgridSegmentsGeom1)
for id2 in wall.CurtainGrid.GetUGridLineIds():
gridLinesGeom1.append(Revit.GeometryConversion.RevitToProtoCurve.ToProtoType(doc.GetElement(id2).FullCurve))
gridLines1.append(doc.GetElement(id2))
UgridSegments1 = []
UgridSegmentsGeom1 = []
for i in doc.GetElement(id2).AllSegmentCurves:
UgridSegments1.append(i)
UgridSegmentsGeom1.append(Revit.GeometryConversion.RevitToProtoCurve.ToProtoType(i,True))
gridSegments2.append(UgridSegments1)
gridSegmentsGeom2.append(UgridSegmentsGeom1)
gridSegments.append(gridSegments2)
gridSegmentsGeom.append(gridSegmentsGeom2)
gridLines.append(gridLines1)
gridLinesGeom.append(gridLinesGeom1)
boolFilter = [[[[b.DoesIntersect(x) for x in d] for d in z] for b in a] for a,z in zip(projectedCrvs, gridSegmentsGeom)]
boolFilter2 = [[[b.DoesIntersect(x) for x in z] for b in a] for a,z in zip(projectedCrvs, gridLinesGeom)]
##Select gridline segments that intersect with centerpoint of projected lines
for x,y in zip(boolFilter,gridSegments):
keySegments2 = []
keySegmentsGeom2 = []
for z in x:
keySegments1 = []
keySegmentsGeom1 = []
for g,l in zip(z,y):
for d,m in zip(g,l):
if d == True:
keySegments1.append(m)
keySegmentsGeom1.append(Revit.GeometryConversion.RevitToProtoCurve.ToProtoType(m,True))
keySegments2.append(keySegments1)
keySegmentsGeom2.append(keySegmentsGeom1)
keySegments.append(keySegments2)
keySegmentsGeom.append(keySegmentsGeom2)
##Order gridlines according to intersection with projected points
for x,y in zip(boolFilter2, gridLines):
keyGridLines1 = []
keyGridLinesGeom1 = []
for z in x:
for g,l in zip(z,y):
if g == True:
keyGridLines1.append(l)
keyGridLinesGeom1.append(Revit.GeometryConversion.RevitToProtoCurve.ToProtoType(l.FullCurve,True))
keyGridLines.append(keyGridLines1)
keyGridLinesGeom.append(keyGridLinesGeom1)
##Add mullions at intersected gridline segments
TransactionManager.Instance.TransactionTaskDone()
TransactionManager.Instance.EnsureInTransaction(doc)
for x,y,z in zip(keyGridLines,keySegments,isPrimary):
projectedGridlines1 = []
for h,j,k in zip(x,y,z):
for i in j:
if i != None:
h.AddMullions(i,mullionType,k)
projectedGridlines1.append(h)
projectedGridlines.append(projectedGridlines1)
else:
None
if toggle == True:
OUT = projectedGridlines
else:
None
TransactionManager.Instance.TransactionTaskDone()
对于代码的混乱表示歉意,这是对我一直在处理的另一个节点的修改。感谢您的帮助。
博,
您的问题根源在于 Dynamo 如何包装元素以用于其自己的模型。最后一个电话 .ToDSType(True)
是问题的要点。 MullionType class 是 Revit 中 ElementType class 的子class(它继承属性)。当 Dynamo 团队将该对象包装到自定义包装器中时,他们只编写了一个对所有 ElementType 都一视同仁的顶级包装器,因此这会输出一个 ElementType/FamilyType 而不是特定的 MullionType。
首先,我建议您替换代码中的代码行:
mullionType = IN[3]
与:
mullionType = UnwrapElement(IN[3])
这是他们用于展开元素的内置方法,用于调用 Revit API。
如果这仍然是一个问题,您可以尝试再次检索 MullionType 对象,这次是直接在您的脚本中,然后再使用它。您可以这样做:
for x,y,z in zip(keyGridLines,keySegments,isPrimary):
projectedGridlines1 = []
for h,j,k in zip(x,y,z):
for i in j:
if i != None:
h.AddMullions(i,doc.GetElement(mullionType.Id),k)
projectedGridlines1.append(h)
projectedGridlines.append(projectedGridlines1)
这应该确保您在包装之前获得 MullionType 元素。
同样,先尝试解包,如果首先不起作用,则调用 GetElement()。
我正在编写一个 Python 脚本,该脚本接受一组输入线并将竖框分配给它们相交的相应网格线。但是,我收到一个奇怪的错误:
我不知道如何在脚本结尾处更正。 Python 告诉我它需要一个 MullionType 并得到一个 Family Type(见图)。我使用的是 Spring 节点的 Collector.WallTypes 的修改版本,它收集竖梃类型,但节点的输出是脚本不接受的族类型。知道如何让 Mullion Type 进入最终的 Python 节点吗?
Spring节点脚本:
#Copyright(c) 2016, Dimitar Venkov
# @5devene, dimitar.ven@gmail.com
import clr
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
doc = DocumentManager.Instance.CurrentDBDocument
clr.AddReference("RevitAPI")
from Autodesk.Revit.DB import *
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
def tolist(obj1):
if hasattr(obj1,"__iter__"): return obj1
else: return [obj1]
fn = tolist(IN[0])
fn = [str(n) for n in fn]
result, similar, names = [], [], []
fec = FilteredElementCollector(doc).OfClass(MullionType)
for i in fec:
n1 = Element.Name.__get__(i)
names.append(n1)
if any(fn1 == n1 for fn1 in fn):
result.append(i.ToDSType(True))
elif any(fn1.lower() in n1.lower() for fn1 in fn):
similar.append(i.ToDSType(True))
if len(result) > 0:
OUT = result,similar
if len(result) == 0 and len(similar) > 0:
OUT = "No exact match found. Check partial below:",similar
if len(result) == 0 and len(similar) == 0:
OUT = "No match found! Check names below:", names
SpringNodes 脚本输出族类型,即使收集器用于竖梃类型(见上图)
这是我的脚本:
import clr
# Import RevitAPI
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *
# Import DocumentManager and TransactionManager
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
# Import ToDSType(bool) extension method
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.GeometryConversion)
from System import Array
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
import math
doc = DocumentManager.Instance.CurrentDBDocument
app = DocumentManager.Instance.CurrentUIApplication.Application
walls = UnwrapElement(IN[0])
toggle = IN[1]
inputLine = IN[2]
mullionType = IN[3]
wallSrf = []
heights = []
finalPoints = []
directions = []
isPrimary = []
projectedCrvs = []
keySegments = []
keySegmentsGeom = []
gridSegments = []
gridSegmentsGeom = []
gridLines = []
gridLinesGeom = []
keyGridLines = []
keyGridLinesGeom = []
projectedGridlines = []
lineDirections = []
gridLineDirection = []
allTrueFalse = []
if toggle == True:
TransactionManager.Instance.EnsureInTransaction(doc)
for w, g in zip(walls,inputLine):
pointCoords = []
primary = []
## Get curtain wall element sketch line
originLine = Revit.GeometryConversion.RevitToProtoCurve.ToProtoType( w.Location.Curve, True )
originLineLength = w.Location.Curve.ApproximateLength
## Get curtain wall element height, loft to create surface
for p in w.Parameters:
if p.Definition.Name == 'Unconnected Height':
height = p.AsDouble()
topLine = originLine.Translate(0,0,height)
srfCurves = [originLine,topLine]
wallSrf = NurbsSurface.ByLoft(srfCurves)
## Get centerpoint of curve, determine whether it extends across entire gridline
projectedCrvCenterpoint = []
for d in g:
lineDirection = d.Direction.Normalized()
lineDirections.append(lineDirection)
curveProject= d.PullOntoSurface(wallSrf)
if abs(lineDirection.Z) == 1:
if curveProject.Length >= height-.5:
primary.append(False)
else:
primary.append(True)
else:
if curveProject.Length >= originLineLength-.5:
primary.append(False)
else:
primary.append(True)
centerPoint = curveProject.PointAtParameter(0.5)
pointList = []
projectedCrvCenterpoint.append(centerPoint)
## Project centerpoint of curve onto wall surface
for h in [centerPoint]:
pointUnwrap = UnwrapElement(centerPoint)
pointList.append(pointUnwrap.X)
pointList.append(pointUnwrap.Y)
pointList.append(pointUnwrap.Z)
pointCoords.append(pointList)
finalPoints.append(pointCoords)
isPrimary.append(primary)
projectedCrvs.append(projectedCrvCenterpoint)
TransactionManager.Instance.TransactionTaskDone()
TransactionManager.Instance.EnsureInTransaction(doc)
##Gather all segments of gridline geometry
for wall in UnwrapElement(walls):
gridSegments2 = []
gridSegmentsGeom2 = []
gridLines1 = []
gridLinesGeom1 = []
for id1 in wall.CurtainGrid.GetVGridLineIds():
gridLinesGeom1.append(Revit.GeometryConversion.RevitToProtoCurve.ToProtoType(doc.GetElement(id1).FullCurve))
gridLines1.append(doc.GetElement(id1))
VgridSegments1 = []
VgridSegmentsGeom1 = []
for i in doc.GetElement(id1).AllSegmentCurves:
VgridSegments1.append(i)
VgridSegmentsGeom1.append(Revit.GeometryConversion.RevitToProtoCurve.ToProtoType(i,True))
gridSegments2.append(VgridSegments1)
gridSegmentsGeom2.append(VgridSegmentsGeom1)
for id2 in wall.CurtainGrid.GetUGridLineIds():
gridLinesGeom1.append(Revit.GeometryConversion.RevitToProtoCurve.ToProtoType(doc.GetElement(id2).FullCurve))
gridLines1.append(doc.GetElement(id2))
UgridSegments1 = []
UgridSegmentsGeom1 = []
for i in doc.GetElement(id2).AllSegmentCurves:
UgridSegments1.append(i)
UgridSegmentsGeom1.append(Revit.GeometryConversion.RevitToProtoCurve.ToProtoType(i,True))
gridSegments2.append(UgridSegments1)
gridSegmentsGeom2.append(UgridSegmentsGeom1)
gridSegments.append(gridSegments2)
gridSegmentsGeom.append(gridSegmentsGeom2)
gridLines.append(gridLines1)
gridLinesGeom.append(gridLinesGeom1)
boolFilter = [[[[b.DoesIntersect(x) for x in d] for d in z] for b in a] for a,z in zip(projectedCrvs, gridSegmentsGeom)]
boolFilter2 = [[[b.DoesIntersect(x) for x in z] for b in a] for a,z in zip(projectedCrvs, gridLinesGeom)]
##Select gridline segments that intersect with centerpoint of projected lines
for x,y in zip(boolFilter,gridSegments):
keySegments2 = []
keySegmentsGeom2 = []
for z in x:
keySegments1 = []
keySegmentsGeom1 = []
for g,l in zip(z,y):
for d,m in zip(g,l):
if d == True:
keySegments1.append(m)
keySegmentsGeom1.append(Revit.GeometryConversion.RevitToProtoCurve.ToProtoType(m,True))
keySegments2.append(keySegments1)
keySegmentsGeom2.append(keySegmentsGeom1)
keySegments.append(keySegments2)
keySegmentsGeom.append(keySegmentsGeom2)
##Order gridlines according to intersection with projected points
for x,y in zip(boolFilter2, gridLines):
keyGridLines1 = []
keyGridLinesGeom1 = []
for z in x:
for g,l in zip(z,y):
if g == True:
keyGridLines1.append(l)
keyGridLinesGeom1.append(Revit.GeometryConversion.RevitToProtoCurve.ToProtoType(l.FullCurve,True))
keyGridLines.append(keyGridLines1)
keyGridLinesGeom.append(keyGridLinesGeom1)
##Add mullions at intersected gridline segments
TransactionManager.Instance.TransactionTaskDone()
TransactionManager.Instance.EnsureInTransaction(doc)
for x,y,z in zip(keyGridLines,keySegments,isPrimary):
projectedGridlines1 = []
for h,j,k in zip(x,y,z):
for i in j:
if i != None:
h.AddMullions(i,mullionType,k)
projectedGridlines1.append(h)
projectedGridlines.append(projectedGridlines1)
else:
None
if toggle == True:
OUT = projectedGridlines
else:
None
TransactionManager.Instance.TransactionTaskDone()
对于代码的混乱表示歉意,这是对我一直在处理的另一个节点的修改。感谢您的帮助。
博,
您的问题根源在于 Dynamo 如何包装元素以用于其自己的模型。最后一个电话 .ToDSType(True)
是问题的要点。 MullionType class 是 Revit 中 ElementType class 的子class(它继承属性)。当 Dynamo 团队将该对象包装到自定义包装器中时,他们只编写了一个对所有 ElementType 都一视同仁的顶级包装器,因此这会输出一个 ElementType/FamilyType 而不是特定的 MullionType。
首先,我建议您替换代码中的代码行:
mullionType = IN[3]
与:
mullionType = UnwrapElement(IN[3])
这是他们用于展开元素的内置方法,用于调用 Revit API。
如果这仍然是一个问题,您可以尝试再次检索 MullionType 对象,这次是直接在您的脚本中,然后再使用它。您可以这样做:
for x,y,z in zip(keyGridLines,keySegments,isPrimary):
projectedGridlines1 = []
for h,j,k in zip(x,y,z):
for i in j:
if i != None:
h.AddMullions(i,doc.GetElement(mullionType.Id),k)
projectedGridlines1.append(h)
projectedGridlines.append(projectedGridlines1)
这应该确保您在包装之前获得 MullionType 元素。
同样,先尝试解包,如果首先不起作用,则调用 GetElement()。