隐蔽的API:基于RevitNET操作Revit文档。

前言:
RevitNET是官方提供的一个可以脱离软件UI界面直接对Revit文件进行操作的一个库,目前主要应用于后台解析文件模型数据,进行后台转换然后轻量化展示,但是很多人都没有通过RevitNET对文件模型进行操作,本文主要对模型的创建以及一些过程中遇到的问题进行一个简单的示例。
注意:
本文仅以研究兴趣出发,由于该接口为非官方接口,不推荐大家使用,另revit2022已不支持该接口的使用!
本文仅以研究兴趣出发,由于该接口为非官方接口,不推荐大家使用,另revit2022已不支持该接口的使用!
本文仅以研究兴趣出发,由于该接口为非官方接口,不推荐大家使用,另revit2022已不支持该接口的使用!
重要的事情说三遍。

在研究过程中,主要参考了以下两位的文章:
https://blog.csdn.net/weixin_44631419/article/details/119822872
https://www.cnblogs.com/minhost/p/11927361.html

准备工作

  1. 新建应用程序项目,并将目标平台修改为X64(必须
  2. 添加引用文件(RevitApi.dll、RevitNET.dll、RevitAddInUtility.dll),三个文件都有严格的版本限制,如果仅对单一版本文件进行操作,可将文件引用到项目中,如果进行多版本项目功能开发,建议是做成多版本模式,不同版本引用不同的库。

RevitNET操作代码示例

using Autodesk.Revit;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Structure;
using Autodesk.RevitAddIns;
using System;
using System.IO;
using System.Linq;
using System.Reflection;

namespace RevitNetDemo
{
    class Program
    {
        static readonly string[] Searchs = RevitProductUtility.GetAllInstalledRevitProducts().Select(x => x.InstallLocation).ToArray();
        static Program()
        {
            AddEnvironmentPaths(Searchs);
            //对程序集解析失败的时候发生
            AppDomain.CurrentDomain.AssemblyResolve += OnAssemblyResolve;
        }

        ///<summary>
        ///当前的主函数
        ///</summary>
        ///<param name="args"></param>
        [STAThread]
        static void Main(string[] args)
        {

            Product _product = Product.GetInstalledProduct();

            var clientId = new ClientApplicationId(Guid.NewGuid(), "Fangjitx", "BIMAPI");

            // I am authorized by Autodesk to use this UI-less functionality. 必须是此字符串。 Autodesk 规定的.
            _product.Init(clientId, "I am authorized by Autodesk to use this UI-less functionality.");

            var Application = _product.Application;
            Document doc = Application.OpenDocumentFile(@"C:\Users\xx\Desktop\RevitNetDemoFile.rvt");
            var phase = new FilteredElementCollector(doc).OfClass(typeof(Phase)).Cast<Phase>().Where(o => o.Name == "阶段 1").FirstOrDefault();

            using (Transaction tr = new Transaction(doc, "Create by RevitNET"))
            {
                tr.Start();
                var Level = new FilteredElementCollector(doc).OfClass(typeof(Level)).WhereElementIsNotElementType().Cast<Level>().FirstOrDefault();
                var walltype = new FilteredElementCollector(doc).OfClass(typeof(WallType)).WhereElementIsElementType().Cast<WallType>().FirstOrDefault();
                Wall wall = Wall.Create(doc, Line.CreateBound(XYZ.Zero, new XYZ(100, 0, 0)), new ElementId(1740), Level.Id, 1000/304.8,0,false,false);
                wall.get_Parameter(BuiltInParameter.PHASE_CREATED).Set(phase.Id);
                tr.Commit();
            }
            doc.Close(true);
            _product?.Exit();
            Console.ReadKey(true);
        }

        ///<summary>
        ///向系统中添加环境变量
        ///</summary>
        ///<param name="paths"></param>
        static void AddEnvironmentPaths(params string[] paths)
        {
            var path = new[] { Environment.GetEnvironmentVariable("PATH") ?? string.Empty };

            var newPath = string.Join(System.IO.Path.PathSeparator.ToString(), path.Concat(paths));

            Environment.SetEnvironmentVariable("PATH", newPath);
        }

        ///<summary>
        ///程序加载失败
        ///</summary>
        ///<param name="sender"></param>
        ///<param name="args"></param>
        ///<returns></returns>
        private static Assembly OnAssemblyResolve(object sender, ResolveEventArgs args)
        {
            var assemblyName = new AssemblyName(args.Name);

            foreach (var item in Searchs)
            {
                var file = string.Format("{0}.dll", System.IO.Path.Combine(item, assemblyName.Name));

                if (File.Exists(file))
                {
                    return Assembly.LoadFile(file);
                }
            }
            return args.RequestingAssembly;
        }
    }
}

关键代码说明及问题说明:

  • 常见问题,就直接贴参考的信息了,每个问题都进行过验证,解决方案也是没有任何问题的。如下:
  • 在这里插入图片描述

重点

如果光引用参考的内容,那么这篇文章就毫无意义,本文重点在于通过RevitNET创建模型,所以发现了从未发现过的问题,即如下代码片段的内容,以创建墙为例:

			var phase = new FilteredElementCollector(doc).OfClass(typeof(Phase)).Cast<Phase>().Where(o => o.Name == "阶段 1").FirstOrDefault();
            using (Transaction tr = new Transaction(doc, "Create by RevitNET"))
            {
                tr.Start();
                var Level = new FilteredElementCollector(doc).OfClass(typeof(Level)).WhereElementIsNotElementType().Cast<Level>().FirstOrDefault();
                var walltype = new FilteredElementCollector(doc).OfClass(typeof(WallType)).WhereElementIsElementType().Cast<WallType>().FirstOrDefault();
                Wall wall = Wall.Create(doc, Line.CreateBound(XYZ.Zero, new XYZ(100, 0, 0)), new ElementId(1740), Level.Id, 1000/304.8,0,false,false);
                wall.get_Parameter(BuiltInParameter.PHASE_CREATED).Set(phase.Id);
                tr.Commit();
            }

我们常用的创建墙调用方法WALL.Create()方法,然后选择适合的重写函数传参数进去即可完成,但是,通过RevitNET创建时,整个程序运行完成后,打开文件发现了很奇怪的现象,如下所示:
![在这里插入图片描述](https://img-blog.csdnimg.cn/fee68de3cbc1404598c053964de2e9a2.png
在这里插入图片描述
模型明明被创建出来了,使用工具能够获取到,但是,不论是调整视图范围、视图的类别可见性都无法使模型可见,后来通过咨询BIM专家涂所,发现模型的“创建的阶段”这个我们平时基本不会去了解的属性出了问题。
在这里插入图片描述
后续又尝试了其它系统族和多个可载入族后发现,通过RevitNET创建的模型,创建的阶段全为阶段3,而手动创建的模型这个属性值为阶段1,所以导致模型不可见
这里又发现了一些可能隐藏的参数,那就是这个不同阶段,可能通过不同的方式创建出来的默认值不同,具体需要进一步研究,后续再更新。
那么问题找到了,如何解决问题,就简单了。很有意思的是,这个属性的属性值类型为ElementId类型,然后发现这个“阶段”类别,竟然在Revit中内置了,于是就有了以下代码:

 var phase = new FilteredElementCollector(doc).OfClass(typeof(Phase)).Cast<Phase>().Where(o => o.Name == "阶段 1").FirstOrDefault();
 wall.get_Parameter(BuiltInParameter.PHASE_CREATED).Set(phase.Id);

每次创建模型时,都将模型的"创建的阶段"修改为“阶段 1”就解决了。

作者简介

感谢各位的查阅,
作者:陈逼仔(464905795、464880906、983855234)

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Gaga.boom

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值