2015-12-13 18 views
5

Mam pytanie dla niektórych z was, którzy są zaznajomieni z API Revit i Python:tworzenie i przypisywanie podkategorii w programie Revit za pomocą Pythona

Używam pakiet węzłów Wiosna w dynamo stworzyć dość dużą serię obiektów o dowolnej wielkości w ich własnej rodzinie. Sposób, w jaki działa FamilyInstance.ByGeometry, pobiera listę brył i tworzy instancję rodziny dla każdego przy użyciu pliku rodziny szablonów. Wynik jest całkiem dobry. (węzły sprężynowe można znaleźć tutaj: https://github.com/dimven/SpringNodes)

Jednak wadą jest to, że mam teraz około 200 oddzielnych przypadków, więc wprowadzenie zmian w każdym z nich jest dość bolesne. Początkowo sądziłem, że będzie możliwe użycie dynamo do stworzenia nowej podkategorii i ustawienia bryły wewnątrz każdej rodziny na tę nową podkategorię. Niestety zdałem sobie sprawę, że nie jest to możliwe, ponieważ dynamo nie może być otwarte jednocześnie w dwóch różnych środowiskach Revit (projekt, w którym pracuję i każde wystąpienie rodziny). To prowadzi mnie do sprawdzenia, czy mogę to zrobić za pomocą Pythona.

Użyłem Pythona w rhino i mogę się dogadać całkiem dobrze, wciąż jednak uczę się API Revita. Ale w zasadzie mój pomysł polegałby na: 1. Wybraniu serii instancji rodzinnych w środowisku projektu Revit 2. Przeprowadź pętlę dla każdej instancji 3. zapisz ją w określonej lokalizacji 4. utwórz nową podkategorię w każdej instancji rodziny (podkategoria będzie taka sama dla wszystkich wybranych przypadkach rodzinnych) 5. wybrać osad w każdej z instancji 6. ustaw stały do ​​tej nowo utworzonej podkategorii 7. blisko wystąpienie rodziny i zapisać

Moje pytanie do ciebie Czy brzmi to tak, jak można to osiągnąć na podstawie znajomości API Revit?

Dziękujemy za poświęcony czas i porady.


UPDATE:

Znalazłem rozdział w API Revit, który opisuje to, czego szukam zrobić: http://help.autodesk.com/view/RVT/2015/ENU/?guid=GUID-FBF9B994-ADCB-4679-B50B-2E9A1E09AA48

Zrobiłem pierwszą przepustkę na włożenie tego do kod Pythona węzła dynamo. Reszta kodu działa dobrze, z wyjątkiem dodania nowej sekcji (patrz poniżej). Proszę wybaczyć zmienne, ja po prostu zgodnie z logiką pierwotnego autora kodu jestem hacking:

(uwaga: zmienne są w są w tablicach)

#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 

Każda pomoc lub poradę z tym sekcja kodu byłaby bardzo doceniana.


UPDATE: Zobacz pełny kod poniżej dla kontekście omawianego odcinka:

#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." 

Aktualizacja:

był w stanie uzyskać to działa:

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 

Odpowiedz

0

Gdy odpowiadam w pierwszym kwerendzie na wiadomość e-mail, to, co chcesz osiągnąć, brzmi dla mnie doskonale w interfejsie API Revit. Gratuluję zdobycia tak daleko, jak to tylko możliwe. Patrząc na link do pliku pomocy programu Revit API i poradnika dla programistów, który cytujesz powyżej, wydaje się, że kod musi zostać wykonany w dokumencie rodziny podczas definiowania rodziny. Kontekst, w którym próbujesz go wykonać, nie jest jasny. Czy korzystałeś z EditFamily do otwarcia dokumentu definicji rodziny? W jakim kontekście realizujesz?

+0

Postanowiłem, że zamiast pętli w każdej rodzinie i edycji go, będę edytować oryginalny kod Pythona na wykresie dynamo z wtyczki wiosny węzłów. W kodzie tego węzła bryły są umieszczane w nowej rodzinie utworzonej z pliku szablonu rodziny. Część opublikowanego przeze mnie kodu działa już w samej rodzinie, tworząc swobodną geometrię, ustawiając kategorię, dodając materiał i tak dalej. Dodaję tylko część podkategorii. Mogę "próbować opublikować pełny kod ... – LuebkerJ

+0

Właśnie dostałem go do pracy z jakąś pomocą z college'u w pracy ... najpierw musiałem przekazać zmienną, a nie nazwę zmiennej w części podkategorii create. Po drugie działałem w niewłaściwym def dla mojej wersji rewitalizacji. Wysłałem poprawiony kod jako aktualizację powyżej. – LuebkerJ

Powiązane problemy