2016-02-19 467 views
1

我試圖通過在項目文檔中調用族的文檔並使用FamilyManager方法編輯族來創建新的族參數。 Dynamo論壇上有大約10個人要求這樣做,所以我想我會試一試。這裏是我的Python腳本如下:Revit API和Dynamo,從項目文檔創建族參數

import clr 
clr.AddReference('ProtoGeometry') 
from Autodesk.DesignScript.Geometry import * 

clr.AddReference("RevitServices") 
from RevitServices.Persistence import DocumentManager 
from RevitServices.Transactions import TransactionManager 

clr.AddReference("RevitAPI") 
from Autodesk.Revit.DB import * 
#The inputs to this node will be stored as a list in the IN variables. 

familyInput = UnwrapElement(IN[0]) 

familySymbol = familyInput.Symbol.Family 
doc = familySymbol.Document 

par_name = IN[1] 
par_type = ParameterType.Text 
par_grp = BuiltInParameterGroup.PG_DATA 


TransactionManager.Instance.EnsureInTransaction(doc) 

familyDoc = doc.EditFamily(familySymbol) 
OUT = familyDoc.FamilyManager.AddParameter(par_name,par_grp,par_type,False) 

TransactionManager.Instance.TransactionTaskDone() 

當我運行該腳本,我得到這個錯誤:

Warning: IronPythonEvaluator.EvaluateIronPythonScript operation failed. 
Traceback (most recent call last): 
    File "<string>", line 26, in <module> 
Exception: The document is currently modifiable! Close the transaction before calling EditFamily. 

我假設,這個錯誤是因爲我打開一個已經存在通過家庭文件該腳本,然後永遠不會將信息發回給項目文件?或者類似的東西。有關如何解決此問題的任何提示?

回答

1

我們從論壇討論構建:

import clr 

clr.AddReference("RevitServices") 
from RevitServices.Persistence import DocumentManager 
from RevitServices.Transactions import TransactionManager 
doc = DocumentManager.Instance.CurrentDBDocument 

clr.AddReference("RevitAPI") 
from Autodesk.Revit.DB import * 

par_name = IN[0] 
exec("par_type = ParameterType.%s" % IN[1]) 
exec("par_grp = BuiltInParameterGroup.%s" % IN[2]) 
inst_or_typ = IN[3] 
families = UnwrapElement(IN[4]) 

# class for overwriting loaded families in the project 
class FamOpt1(IFamilyLoadOptions): 
    def __init__(self): pass 
    def OnFamilyFound(self,familyInUse, overwriteParameterValues): return True 
    def OnSharedFamilyFound(self,familyInUse, source, overwriteParameterValues): return True 

trans1 = TransactionManager.Instance 
trans1.ForceCloseTransaction() #just to make sure everything is closed down 
# Dynamo's transaction handling is pretty poor for 
# multiple documents, so we'll need to force close 
# every single transaction we open 
result = [] 

for f1 in families: 
    famdoc = doc.EditFamily(f1) 
    try: # this might fail if the parameter exists or for some other reason 
     trans1.EnsureInTransaction(famdoc) 
     famdoc.FamilyManager.AddParameter(par_name, par_grp, par_type, inst_or_typ) 
     trans1.ForceCloseTransaction() 
     famdoc.LoadFamily(doc, FamOpt1()) 
     result.append(True) 
    except: #you might want to import traceback for a more detailed error report 
     result.append(False) 
     trans1.ForceCloseTransaction()  
    famdoc.Close(False) 

OUT = result 

image of the Dynamo graph

+0

曾任職!謝謝,Dimitar。一個註釋:我添加了一行來改變家庭的家庭類型輸入(f1.Family),以便EditFamily方法可以運行。除此之外,像魅力一樣工作。你能解釋一下FamOpt1類是如何工作的嗎?我意識到它來自API,但我不太明白。 – stdmn

+0

另外,您應該將其打包到自定義節點中。似乎在論壇上很感興趣。 – stdmn

+0

如果您正在餵養家庭符號,則只需提取家庭財產。在我的例子中,我正在餵養實際的家庭。 FamOpt1是內置Revit類的粗糙包裝。如果可以重寫項目系列的話,如果可以複製的話,如果需要API,它會返回你的答案。 (在上述情況下是固定的,或者是) – dimven

0

錯誤消息已經告訴你到底是什麼問題:「文檔當前是可修改的!在調用EditFamily之前關閉事務」。

我假設TransactionManager.Instance.EnsureInTransaction在給定的文檔上打開一個事務。您無法通過打開的事務調用EditFamily。

即在幫助文件中明確記載:

http://thebuildingcoder.typepad.com/blog/2012/05/edit-family-requires-no-transaction.html

調用EditFamily之前完成交易,或者,在這種情況下,不要打開它在所有的開始。

哦,然後,當然,你想修改家庭文件。這確實需要交易,但是在家庭文檔'familyDoc'上,而不是在項目文檔'doc'上。

我不知道這是否將是最終的解決方案,但它可能會幫助:

familyDoc = doc.EditFamily(familySymbol) 

TransactionManager.Instance.EnsureInTransaction(familyDoc) 
OUT = familyDoc.FamilyManager.AddParameter(par_name,par_grp,par_type,False) 
TransactionManager.Instance.TransactionTaskDone()