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