2016-02-16 48 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