2015-12-13 43 views
5

我有一些你們誰是熟悉的Revit API和python問題分配在Revit子類別:創建和使用python

我一直在使用的春天節點包發電機產生相當大系列各自在自己的家庭中的自由形式對象。 FamilyInstance.ByGeometry的工作方式是,它採用實體列表並使用模板族文件爲每個實例創建一個族實例。結果非常好。 (可以在這裏找到彈簧節點:https://github.com/dimven/SpringNodes

然而,缺點是現在我有大約200個單獨的實例,所以對每個實例進行更改都是相當痛苦的。我首先想到可以使用發電機來創建一個新的子類別,並將每個家族實例內部的固體設置爲這個新的子類別。不幸的是,我意識到這是不可能的,因爲發電機不能在兩個不同的Revit環境中同時打開(我正在工作的項目和家庭的每個實例)。這導致我看看是否可以使用python來做到這一點。

我在犀牛中使用過python,可以相處得很好,但我仍然在學習Revit API。但基本上我的想法是: 1.在Revit項目環境中選擇一系列家族實例 2.循環遍歷每個實例 3.將其保存到指定位置 4.在每個家族實例中創建一個新的子類別(子類別會爲所有選定的家庭情況相同) 5.每個實例 6.選擇牢固的設置固體這個新創建的子類別 7.關閉家庭實例,並保存

我的問題要問你這聽起來像是基於您對Revit API的瞭解可以實現的嗎?

非常感謝您的時間和建議。


UPDATE:

我發現在Revit API一節,描述了什麼,我希望做的:http://help.autodesk.com/view/RVT/2015/ENU/?guid=GUID-FBF9B994-ADCB-4679-B50B-2E9A1E09AA48

我在插入本作第一遍發電機節點的python代碼。除了即將添加的新部分之外,其餘代碼都可以正常工作(請參見下文)。請原諒變量,我只是用我的代碼我黑客的原作者的邏輯保持:

(注:變量進來是數組)

#set subcategory  
try: 
    #create new sucategory 
    fam_subcat = famdoc.Settings.Categories.NewSubcategory(fam_cat, get_Item(subcat1.Name))     

    #assign the mataterial(fam_mat.Id) to the subcategory 
    fam_subcat.Material = famdoc.GetElement(fam_mat.Id) 

    #assign the subcategory to the element (s2) 
    s2.Subcategory = fam_subcat 
except: pass 

任何幫助或建議,與此部分代碼將不勝感激。


UPDATE: 請參見下面完整的代碼有問題的部分的情況下:

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

import clr 
import System 
from System.Collections.Generic import * 

pf_path = System.Environment.GetFolderPath(System.Environment.SpecialFolder.ProgramFilesX86) 
import sys 
sys.path.append("%s\IronPython 2.7\Lib" %pf_path) 
import traceback 

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

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

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

clr.AddReference("RevitNodes") 
import Revit 
clr.ImportExtensions(Revit.Elements) 
clr.ImportExtensions(Revit.GeometryConversion) 

def tolist(obj1): 
    if hasattr(obj1,"__iter__"): return obj1 
    else: return [obj1] 

def output1(l1): 
    if len(l1) == 1: return l1[0] 
    else: return l1 

def PadLists(lists): 
    len1 = max([len(l) for l in lists]) 
    for i in xrange(len(lists)): 
     if len(lists[i]) == len1: 
      continue 
     else: 
      len2 = len1 - len(lists[i]) 
      for j in xrange(len2): 
       lists[i].append(lists[i][-1]) 
    return lists 

class FamOpt1(IFamilyLoadOptions): 
    def __init__(self): 
     pass 
    def OnFamilyFound(self,familyInUse, overwriteParameterValues): 
     return True 
    def OnSharedFamilyFound(self,familyInUse, source, overwriteParameterValues): 
     return True 

geom = tolist(IN[0]) 
fam_path = IN[1] 
names = tolist(IN[2]) 
category = tolist(IN[3]) 
material = tolist(IN[4]) 
isVoid = tolist(IN[5]) 
subcategory = tolist(IN[6]) 

isRvt2014 = False 
if app.VersionName == "Autodesk Revit 2014": isRvt2014 = True 
units = doc.GetUnits().GetFormatOptions(UnitType.UT_Length).DisplayUnits 
factor = UnitUtils.ConvertToInternalUnits(1,units) 
acceptable_views = ["ThreeD", "FloorPlan", "EngineeringPlan", "CeilingPlan", "Elevation", "Section"] 
origin = XYZ(0,0,0) 
str_typ = StructuralType.NonStructural 

def NewForm_background(s1, name1, cat1, isVoid1, mat1, subcat1): 
    t1 = TransactionManager.Instance 
    TransactionManager.ForceCloseTransaction(t1) 
    famdoc = doc.Application.NewFamilyDocument(fam_path) 
    message = None 
    temp_path = System.IO.Path.GetTempPath() 
    sat_path = "%s%s.sat" % (temp_path, name1) 
    try: 
     if factor != 1: 
      s1 = s1.Scale(factor) 
     sat1 = Geometry.ExportToSAT(s1, sat_path) 
     satOpt = SATImportOptions() 
     satOpt.Placement = ImportPlacement.Origin 
     satOpt.Unit = ImportUnit.Foot 
     view_fec = FilteredElementCollector(famdoc).OfClass(View) 
     view1 = None 
     for v in view_fec: 
      if str(v.ViewType) in acceptable_views: 
       view1 = v 
       break 
     t1.EnsureInTransaction(famdoc) 
     satId = famdoc.Import(sat1, satOpt, view1) 
     opt1 = Options() 
     opt1.ComputeReferences = True 
     el1 = famdoc.GetElement(satId) 
     geom1 = el1.get_Geometry(opt1) 
     enum = geom1.GetEnumerator() 
     enum.MoveNext() 
     geom2 = enum.Current.GetInstanceGeometry() 
     enum2 = geom2.GetEnumerator() 
     enum2.MoveNext() 
     s1 = enum2.Current 
     famdoc.Delete(satId) 
     TransactionManager.ForceCloseTransaction(t1) 
     System.IO.File.Delete(sat_path) 
    except: 
     message = traceback.format_exc() 
     pass 
    if message == None: 
     try: 
      save_path = "%s%s.rfa" % (temp_path, name1) 
      SaveAsOpt = SaveAsOptions() 
      SaveAsOpt.OverwriteExistingFile = True 
      t1.EnsureInTransaction(famdoc) 
      #set the category 
      try: 
       fam_cat = famdoc.Settings.Categories.get_Item(cat1.Name) 
       famdoc.OwnerFamily.FamilyCategory = fam_cat 
      except: pass 
      s2 = FreeFormElement.Create(famdoc,s1) 
      if isVoid1: 
       void_par = s2.get_Parameter("Solid/Void") 
       void_par.Set(1) 
       void_par2 = famdoc.OwnerFamily.get_Parameter("Cut with Voids When Loaded") 
       void_par2.Set(1) 
      else: #voids do not have a material value 
       try: 
        mat_fec = FilteredElementCollector(famdoc).OfClass(Material) 
        for m in mat_fec: 
         if m.Name == mat1: 
          fam_mat = m 
          break 
        mat_par = s2.get_Parameter("Material") 
        mat_par.Set(fam_mat.Id) 
       except: pass 
      #set subcategory  
      try: 
       #create new sucategory 
       fam_subcat = document.Settings.Categories.NewSubcategory(document.OwnerFamily.FamilyCategory, get_Item(subcat1.Name))    

       #assign the mataterial(fam_mat.Id) to the subcategory 
       fam_subcat.Material = famdoc.GetElement(fam_mat.Id) 

       #assign the subcategory to the element (s2) 
       s2.Subcategory = fam_subcat 
      except: pass 

      TransactionManager.ForceCloseTransaction(t1) 
      famdoc.SaveAs(save_path, SaveAsOpt) 
      family1 = famdoc.LoadFamily(doc, FamOpt1()) 
      famdoc.Close(False) 
      System.IO.File.Delete(save_path) 
      symbols = family1.Symbols.GetEnumerator() 
      symbols.MoveNext() 
      symbol1 = symbols.Current 
      t1.EnsureInTransaction(doc) 
      if not symbol1.IsActive: symbol1.Activate() 
      inst1 = doc.Create.NewFamilyInstance(origin, symbol1, str_typ) 
      TransactionManager.ForceCloseTransaction(t1) 
      return inst1.ToDSType(False), family1.ToDSType(False) 
     except: 
      message = traceback.format_exc() 
      return message 
    else: 
     return message 

def NewForm_background_R16(s1, name1, cat1, isVoid1, mat1, subcat1): 
    t1 = TransactionManager.Instance 
    TransactionManager.ForceCloseTransaction(t1) 
    famdoc = doc.Application.NewFamilyDocument(fam_path) 
    message = None 
    temp_path = System.IO.Path.GetTempPath() 
    sat_path = "%s%s.sat" % (temp_path, name1) 
    try: 
     if factor != 1: 
      s1 = s1.Scale(factor) 
     sat1 = Geometry.ExportToSAT(s1, sat_path) 
     satOpt = SATImportOptions() 
     satOpt.Placement = ImportPlacement.Origin 
     satOpt.Unit = ImportUnit.Foot 
     view_fec = FilteredElementCollector(famdoc).OfClass(View) 
     view1 = None 
     for v in view_fec: 
      if str(v.ViewType) in acceptable_views: 
       view1 = v 
       break 
     t1.EnsureInTransaction(famdoc) 
     satId = famdoc.Import(sat1, satOpt, view1) 
     opt1 = Options() 
     opt1.ComputeReferences = True 
     el1 = famdoc.GetElement(satId) 
     geom1 = el1.get_Geometry(opt1) 
     enum = geom1.GetEnumerator() 
     enum.MoveNext() 
     geom2 = enum.Current.GetInstanceGeometry() 
     enum2 = geom2.GetEnumerator() 
     enum2.MoveNext() 
     s1 = enum2.Current 
     famdoc.Delete(satId) 
     TransactionManager.ForceCloseTransaction(t1) 
     System.IO.File.Delete(sat_path) 
    except: 
     message = traceback.format_exc() 
     pass 
    if message == None: 
     try: 
      save_path = "%s%s.rfa" % (temp_path, name1) 
      SaveAsOpt = SaveAsOptions() 
      SaveAsOpt.OverwriteExistingFile = True 
      t1.EnsureInTransaction(famdoc) 
      #set the category 
      try: 
       fam_cat = famdoc.Settings.Categories.get_Item(cat1.Name) 
       famdoc.OwnerFamily.FamilyCategory = fam_cat 
      except: pass 
      s2 = FreeFormElement.Create(famdoc,s1) 
      if isVoid1: 
       void_par = s2.LookupParameter("Solid/Void") 
       void_par.Set(1) 
       void_par2 = famdoc.OwnerFamily.LookupParameter("Cut with Voids When Loaded") 
       void_par2.Set(1) 
      else: #voids do not have a material value 
       try: 
        mat_fec = FilteredElementCollector(famdoc).OfClass(Material) 
        for m in mat_fec: 
         if m.Name == mat1: 
          fam_mat = m 
          break 
        mat_par = s2.LookupParameter("Material") 
        mat_par.Set(fam_mat.Id) 
       except: pass 

      #apply same subcategory code as before 
      #set subcategory  
      try: 
       #create new sucategory 
       fam_subcat = famdoc.Settings.Categories.NewSubcategory(fam_cat, get_Item(subcat1.Name))    

       #assign the mataterial(fam_mat.Id) to the subcategory 
       fam_subcat.Material = famdoc.GetElement(fam_mat.Id) 

       #assign the subcategory to the element (s2) 
       s2.Subcategory = fam_subcat 
      except: pass 


      TransactionManager.ForceCloseTransaction(t1) 
      famdoc.SaveAs(save_path, SaveAsOpt) 
      family1 = famdoc.LoadFamily(doc, FamOpt1()) 
      famdoc.Close(False) 
      System.IO.File.Delete(save_path) 
      symbols = family1.GetFamilySymbolIds().GetEnumerator() 
      symbols.MoveNext() 
      symbol1 = doc.GetElement(symbols.Current) 
      t1.EnsureInTransaction(doc) 
      if not symbol1.IsActive: symbol1.Activate() 
      inst1 = doc.Create.NewFamilyInstance(origin, symbol1, str_typ) 
      TransactionManager.ForceCloseTransaction(t1) 
      return inst1.ToDSType(False), family1.ToDSType(False) 
     except: 
      message = traceback.format_exc() 
      return message 
    else: 
     return message 

if len(geom) == len(names) == len(category) == len(isVoid) == len(material) == len(subcategory): 
    if isRvt2014: 
     OUT = output1(map(NewForm_background, geom, names, category, isVoid, material, subcategory)) 
    else: 
     OUT = output1(map(NewForm_background_R16, geom, names, category, isVoid, material, subcategory)) 
elif len(geom) == len(names): 
    padded = PadLists((geom, category, isVoid, material, subcategory)) 
    p_category = padded[1] 
    p_isVoid = padded[2] 
    p_material = padded[3] 
    p_subcategory = padded [4] 
    if isRvt2014: 
     OUT = output1(map(NewForm_background, geom, names, p_category, p_isVoid, p_material, p_subcategory)) 
    else: 
     OUT = output1(map(NewForm_background_R16, geom, names, p_category, p_isVoid, p_material, subcategory)) 
else: OUT = "Make sure that each geometry\nobject has a unique family name." 

更新:

能得到它的工作:

try: 
     #create new sucategory 
     fam_subcat = famdoc.Settings.Categories.NewSubcategory(famdoc.OwnerFamily.FamilyCategory, subcat1)   

     #assign the mataterial(fam_mat.Id) to the subcategory 
     #fam_subcat.Material = famdoc.GetElement(fam_mat.Id) 

     #assign the subcategory to the element (s2) 
     s2.Subcategory = fam_subcat 
    except: pass 

回答

0

正如我回答編輯您的每個電子郵件的初始查詢,您在Revit API中對我的目標聽起來完全可行。祝賀你儘可能多。查看上面引用的Revit API幫助文件和開發人員指南的鏈接,似乎代碼必須在定義族時在族文檔中執行。您嘗試執行的上下文並不清楚。您是否使用EditFamily打開家庭定義文檔?你在執行什麼上下文?

+0

我決定,而不是循環遍歷每個家族並編輯它,我會從spring節點插件編輯dynamo圖中的原始python代碼。在這個節點的代碼中,每個實體都放置在一個由族模板文件創建的新族中。我發佈的代碼部分已經在家族內部操作,創建自由幾何體,設置類別,添加材質等等,我只是添加子類別部分。我可以'嘗試發佈完整的代碼... – LuebkerJ

+0

我剛剛得到它的工作與一個幫助形成一所大學在工作...首先我需要傳遞變量而不是變量的名稱在創建子類別的一部分。其次,我在我的revit版本中運行錯誤的def。我已將更正後的代碼發佈爲上述更新。 – LuebkerJ