2016-02-16 51 views
1

我正在研究一个Python脚本,它接收一组输入行并将竖框指定给它们相交的对应网格线。但是,我得到一个奇怪的错误:Revit API/Dynamo脚本中的MullionType错误

*Expected Mullion Type, Got Family Type*

,我不知道如何对脚本的末尾纠正。 Python告诉我它期望一个MullionType并获得了一个Family Type(见图)。我正在使用收集Mullion Types的Spring Nodes'Collector.WallTypes的修改版本,但节点的输出是一个Family Type,该脚本不会接受。任何想法如何让Mullion类型提供给最终的Python节点?

SpringNodes脚本:

#Copyright(c) 2016, Dimitar Venkov 
# @5devene, [email protected] 

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

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

回答

1

博,

你的问题的根源在于迪纳摩是如何包装元素与自己的模式来使用。最后一次呼吁.ToDSType(True)是问题的要点。 MullionType类是Revit中ElementType类的一个子类(它继承了属性)。当Dynamo团队将该对象包装到自定义包装器中时,他们只写了一个顶级包装器,它将所有ElementTypes都视为相同,因此它输出的是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()调用,如果第一个不起作用。

+0

展开输入工作!解开/ ToDSType问题一直困扰着我的头脑。我注意到从API调用方法时,有些方法需要我创建一个DSType元素,而另一些则不需要。这一切都很混乱。谢谢你的帮助! – stdmn