首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用python在revit中创建和分配子类别

使用python在revit中创建和分配子类别
EN

Stack Overflow用户
提问于 2015-12-13 21:54:32
回答 1查看 2.2K关注 0票数 6

对于熟悉Revit和python的一些人,我有一个问题:

我一直在使用dynamo中的spring节点包来创建一个相当大的自由形式对象系列,每个对象都在他们自己的家庭中。按照FamilyInstance.ByGeometry的工作方式,它接受一个固体列表,并使用一个模板族文件为每个人创建一个系列实例。结果相当好。(在这里可以找到spring节点:https://github.com/dimven/SpringNodes)

然而,缺点是,现在我有大约200个单独的实例,因此对每个实例进行更改都是相当痛苦的。起初,我认为可以使用dynamo创建一个新的子类别,并将每个家庭实例中的实体设置为这个新的子类别。不幸的是,我意识到这是不可能的,因为dynamo不能同时在两个不同的Revit环境中打开(我正在工作的项目以及家庭的每个实例)。这让我想看看我是否可以使用python来完成这个任务。

我已经在犀牛中使用了python,并且可以很好地相处,但是我仍然在学习Revit。但基本上,我的想法是: 1.在Revit项目环境中选择一系列家庭实例;2.遍历每个实例;3.将其保存到指定的位置;4.在每个家族实例中创建一个新的子类别(对于所有选定的家庭实例,子类别相同)。5.在实例6中选择实存。将实体设置为新创建的子类别7。关闭家庭实例并保存

我的问题是,根据您对Revit的了解,这听起来像是可以实现的吗?

非常感谢您的时间和建议。

更新:

我在revit中找到了一个部分,它描述了我想要做的事情:http://help.autodesk.com/view/RVT/2015/ENU/?guid=GUID-FBF9B994-ADCB-4679-B50B-2E9A1E09AA48

我第一次尝试将它插入到dynamo节点的python代码中。除了新的im部分之外,其余代码都能正常工作(请参阅下面的代码)。请原谅这些变量,我只是遵循了我正在破解的代码的原始作者的逻辑:

(注意:输入的变量在数组中)

代码语言:javascript
运行
复制
#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

任何关于这部分代码的帮助或建议都将不胜感激。

更新:有关章节的上下文,请参阅下面的完整代码:

代码语言:javascript
运行
复制
#Copyright(c) 2015, Dimitar Venkov
# @5devene, dimitar.ven@gmail.com

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

更新:

能让它发挥作用:

代码语言:javascript
运行
复制
    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
EN

回答 1

Stack Overflow用户

发布于 2015-12-14 09:02:42

正如我在您最初的每封电子邮件查询中回答的那样,在Revit中,您所针对的目标听起来完全可行。恭喜你已经走得这么远了。查看上面引用的Revit帮助文件和开发人员指南的链接,似乎必须在定义家族时在家族文档中执行代码。您正在尝试执行它的上下文并不清楚。您是否使用EditFamily打开家庭定义文档?您在执行什么上下文?

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34256833

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档