前言:
RevitNET是官方提供的一个可以脱离软件UI界面直接对Revit文件进行操作的一个库,目前主要应用于后台解析文件模型数据,进行后台转换然后轻量化展示,但是很多人都没有通过RevitNET对文件模型进行操作,本文主要对模型的创建以及一些过程中遇到的问题进行一个简单的示例。
注意:
本文仅以研究兴趣出发,由于该接口为非官方接口,不推荐大家使用,另revit2022已不支持该接口的使用!
本文仅以研究兴趣出发,由于该接口为非官方接口,不推荐大家使用,另revit2022已不支持该接口的使用!
本文仅以研究兴趣出发,由于该接口为非官方接口,不推荐大家使用,另revit2022已不支持该接口的使用!
重要的事情说三遍。
在研究过程中,主要参考了以下两位的文章:
https://blog.youkuaiyun.com/weixin_44631419/article/details/119822872
https://www.cnblogs.com/minhost/p/11927361.html
准备工作
- 新建应用程序项目,并将目标平台修改为X64(必须)
- 添加引用文件(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创建时,整个程序运行完成后,打开文件发现了很奇怪的现象,如下所示:
.OfClass(typeof(Phase)).Cast<Phase>().Where(o => o.Name == "阶段 1").FirstOrDefault();
wall.get_Parameter(BuiltInParameter.PHASE_CREATED).Set(phase.Id);
每次创建模型时,都将模型的"创建的阶段"修改为“阶段 1”就解决了。
作者简介
感谢各位的查阅,
作者:陈逼仔(464905795、464880906、983855234)