【问题标题】:Revit API & Dynamo, Creating a Family Parameter from Project DocumentRevit API 和 Dynamo,从项目文档创建族参数
【发布时间】:2018-04-17 01:04:15
【问题描述】:

我正在尝试通过在项目文档中调用族的文档并使用 FamilyManager 方法来编辑族来创建新的族参数。在 Dynamo 论坛上大约有 10 人要求这个,所以我想我会试一试。下面是我的 Python 脚本:

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.

我假设这个错误是因为我通过脚本打开了一个已经存在的家庭文档,然后从未将信息发送回项目文档?或者类似的东西。有关如何解决此问题的任何提示?

【问题讨论】:

    标签: revit-api revitpythonshell


    【解决方案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

    【讨论】:

    • 成功了!谢谢,迪米塔尔。注意:我添加了一小行来将家庭类型输入更改为家庭 (f1.Family),以便可以运行 EditFamily 方法。除此之外,工作就像一个魅力。你能解释一下 FamOpt1 类是如何工作的吗?我意识到它取自 API,但我不太明白。
    • 另外,您应该将其打包到自定义节点中。似乎对论坛很感兴趣。
    • 只有在输入家庭符号时才需要提取 Family 属性。在我的例子中,我在实际的家庭中喂养。 FamOpt1 是内置 Revit 类的粗略包装器。粗略地说,当 revit 询问 API 是否可以重写项目族时,它会返回您的答案。 (在上述情况下,固定为真,或者是)
    【解决方案2】:

    错误消息已经准确地告诉您问题出在哪里:“文档当前可修改!在调用 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()
    

    【讨论】:

      猜你喜欢
      • 2019-03-29
      • 2020-09-15
      • 1970-01-01
      • 2020-10-15
      • 2018-04-22
      • 1970-01-01
      • 2019-08-20
      • 2018-12-20
      • 2015-10-03
      相关资源
      最近更新 更多