2015-12-13 17 views
5

Ich habe eine Frage für einige von Ihnen, die mit der Revit-API und Python vertraut sind:erstellen und zuweisen Unterkategorien in revit mit Python

Ich habe die Feder Knoten Paket in Dynamos wurde unter Verwendung eine ziemlich große Serie zu schaffen von Freiformobjekten jeweils in ihrer eigenen Familie. Die Funktionsweise von FamilyInstance.ByGeometry erfordert eine Liste von Volumenkörpern und erstellt eine Familieninstanz für jede Datei, die eine Vorlagenfamiliendatei verwendet. Das Ergebnis ist ziemlich gut. (Federknoten finden Sie hier: https://github.com/dimven/SpringNodes)

Allerdings ist der Nachteil, dass ich jetzt etwa 200 separate Instanzen habe, so dass Änderungen an jedem ziemlich schmerzhaft sind. Ich dachte zuerst, dass es möglich wäre, Dynamo zu verwenden, um eine neue Unterkategorie zu erstellen und den Körper innerhalb jeder Familieninstanz auf diese neue Unterkategorie zu setzen. Leider wurde mir klar, dass dies nicht möglich ist, da Dynamo nicht gleichzeitig in zwei verschiedenen Revit-Umgebungen geöffnet werden kann (das Projekt, in dem ich arbeite und jede Instanz der Familie). Das führt mich dazu, zu sehen, ob ich das mit Python machen kann.

Ich habe Python im Nashorn verwendet und komme sehr gut zurecht, ich lerne immer noch die Revit API. Aber im Grunde wäre meine Idee zu: 1. Wählen Sie eine Reihe von Familie Instanzen in der Revit-Projektumgebung 2. Schleife durch jede Instanz 3. Speichern Sie es an einem angegebenen Speicherort 4. Erstellen Sie eine neue Unterkategorie in jeder Familie Instanzen (die Unterkategorie würde das gleiche für alle ausgewählten Familie Instanzen) 5. feste wählen in jeder in Beispiel 6. den Feststoff zu dieser neu geschaffenen Unter 7. schließen die Familie Instanz und für Sie

Meine Frage speichern Wie hört sich das an, basierend auf Ihrem Wissen über die Revit-API?

Vielen Dank für Ihre Zeit und Ratschläge.


UPDATE:

ich einen Schnitt in der revit api gefunden habe, was ich bin auf der Suche zu tun, beschreibt: http://help.autodesk.com/view/RVT/2015/ENU/?guid=GUID-FBF9B994-ADCB-4679-B50B-2E9A1E09AA48

ich einen ersten Durchgang bei Einsetzen in die gemacht haben Python-Code des Dynamoknotens. Der Rest des Codes funktioniert gut, mit Ausnahme des neuen Abschnitts im Hinzufügen (siehe unten). Bitte entschuldigen Sie die Variablen, ich bin einfach mit der Logik des ursprünglichen Autors des Codes halten i Hacking bin:

(Hinweis: Die Variablen sind in sind in Arrays)

#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 

Jede Hilfe oder Rat mit diesem Codeabschnitt würde sehr geschätzt werden.


UPDATE: vollständigen Code Siehe unten für den Kontext des Abschnitts in Frage:

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

Update:

Waren in der Lage, es zu bekommen arbeiten:

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 

Antwort

0

Als ich antworte Wenn Sie Ihre erste Anfrage per E-Mail beantworten, klingt das, was Sie anstreben, für mich in der Revit API perfekt. Gratulation, so weit wie möglich zu kommen. Wenn Sie den Link zu der Revit-API-Hilfedatei und dem Entwicklerhandbuch aufrufen, die Sie oben angegeben haben, scheint der Code beim Definieren der Familie im Familiendokument ausgeführt worden zu sein. Der Kontext, in dem Sie versuchen, es auszuführen, ist nicht klar. Haben Sie EditFamily verwendet, um das Familiendefinitionsdokument zu öffnen? In welchem ​​Kontext werden Sie ausgeführt?

+0

Ich entschied, dass ich lieber den ursprünglichen Python-Code in der Dynamo-Grafik aus dem Spring Nodes-Plugin bearbeiten würde, anstatt jede Familie durchzugehen und zu bearbeiten. Im Code dieses Knotens werden die Volumenkörper jeweils in einer neuen Familie platziert, die aus einer Familienvorlagendatei erstellt wird. Der Teil des Codes, den ich gepostet habe, funktioniert bereits in der Familie selbst, erzeugt die Freiform-Geometrie, setzt die Kategorie, fügt ein Material hinzu und so weiter, ich füge einfach den Unterkategorie-Teil hinzu. Ich kann 'versuchen, den vollen Code zu posten ... – LuebkerJ

+0

Ich habe es gerade mit einer Hilfe helfen, ein College bei der Arbeit zu arbeiten ... zuerst musste ich die Variable nicht den Namen der Variablen in der create Subkategorie Teil übergeben. Zweitens arbeitete ich in der falschen Version für meine Version von Revit. Ich habe den korrigierten Code als Update oben veröffentlicht. – LuebkerJ