Revit API / Dynamo脚本中的MullionType错误

时间:2016-02-16 02:04:56

标签: revit-api

我正在研究一个Python脚本,该脚本采用一组输入线并将一条竖框分配给它们相交的相应网格线。但是,我收到一个奇怪的错误:

*Expected Mullion Type, Got Family Type*

我不知道如何纠正脚本的结尾。 Python告诉我它期望MullionType并获得一个Family Type(见图)。我使用的是Spring Nodes的Collector.WallTypes的修改版本,它收集了Mullion类型,但节点的输出是一个Family Type,脚本不接受。知道如何让Mullion Type输入最终的Python节点吗?

SpringNodes脚本:

#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脚本输出一个Family Type,即使收集器是用于Mullion Types(见上图)

这是我的剧本:

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

对于代码混乱的道歉,它是我一直在努力的另一个节点的修改。谢谢你的帮助。

1 个答案:

答案 0 :(得分:1)

您的问题源于Dynamo如何包装要与其自己的模型一起使用的元素。最后一次电话.ToDSType(True)是问题的要点。 MullionType类是Revit中ElementType类的子类(它继承属性)。当Dynamo团队将该对象包装到自定义包装器中时,他们只编写了一个顶级包装器,它将所有ElementTypes视为相同,因此这将输出ElementType / FamilyType而不是特定的MullionType。

首先,我建议您替换代码中的代码行:

mullionType = IN[3] 

with:

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