使用RevitNET.dll通过初始化RevitNet核心类Product后可以在不打开RevitUI界面的情况下后台操作模型文件(支持开启事务)。可以对模型文件进行增、删、查、改等一系列操作,总而言之就等于是没有界面,没有了UI交互,但是一样可以操作Revit。
Product主要属性及方法:
public APISettings Settings { get; }
public Application Application { get; } // 当前的应用程序服务Application对象
public static ICriticalSituationProcessor GetCriticalSituationProcessor();
public static Product GetInstalledProduct();// 获取Product对象
public static void RegisterCriticalSituationProcessor(ICriticalSituationProcessor processor);
public sealed override void Dispose();
public void EnableIFC(bool enable);
public void Exit(); // 退出/关闭应用
public void Init(DB.ClientApplicationId id, string clientData);
public void SetPreferredLanguage(ApplicationServices.LanguageType language);
public void SetSettingsFileLocation(string strSettingsFileLocation);
一、新建控制台应用程序
二、修改目标平台为x64(.Net Core项目配置文件)
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net48</TargetFramework>
<Platforms>AnyCPU;x64</Platforms>
</PropertyGroup>
1
2
3
4
5
三、添加相关依赖
RevitNET.dll
RevitAPI.dll
RevitAddinUtity.dll
四、函数入口方法(Main)添加特性[STAThread]
[STAThread]
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
}
1
2
3
4
5
Example
以下代码演示如何初始化Product类然后已知的Revit文件进行数据读取,过滤出项目中“墙”、“结构柱”、“楼板”并将他们的Id打印出来。
using System;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using Autodesk.Revit;
using Autodesk.Revit.DB;
using Autodesk.RevitAddIns;
namespace LjsGo.RevitNetDemo
{
class Program
{
// 获取已经安装的Revit版本路径
static readonly string[] Searchs =
RevitProductUtility.GetAllInstalledRevitProducts()
.Select(x => x.InstallLocation).ToArray();
private static string filePath = @"C:\Users\Don\Desktop\项目1.rvt";
private static string productInstalledPath = "";
private static string revitVersion = "";
static Program()
{
// 将Revit应用程序路径写入环境变量
revitVersion = GetVersion(filePath);
productInstalledPath = $"C:\\Program Files\\Autodesk\\Revit {revitVersion}";
AddEnvironmentPaths(Searchs);
AppDomain.CurrentDomain.AssemblyResolve += OnAssemblyResolve;
}
[STAThread]
static void Main(string[] args)
{
Product product = Product.GetInstalledProduct();
var clientId = new ClientApplicationId(Guid.NewGuid(), "Don", "BIMAPI");
product.Init(clientId, "I am authorized by Autodesk to use this UI-less functionality.");
var Application = product.Application;
Document doc = Application.OpenDocumentFile(filePath);
Console.WriteLine($"文件名称:{doc.Title}");
Console.WriteLine($"文件版本:{ revitVersion}");
FilteredElementCollector wallCollector = new FilteredElementCollector(doc);
var walls = wallCollector.OfClass(typeof(Wall)).ToArray();
foreach (Wall wall in walls)
{
Console.WriteLine("Wall ElementId:{0}", wall.Id.IntegerValue);
}
collector = new FilteredElementCollector(doc);
var columns = collector.OfClass(typeof(FamilyInstance)).OfCategory(BuiltInCategory.OST_StructuralColumns).ToList();
foreach (FamilyInstance column in columns)
{
Console.WriteLine("Column ElementId:{0}", column.Id.IntegerValue);
}
collector = new FilteredElementCollector(doc);
var floors = collector.OfClass(typeof(Floor)).ToList();
foreach (Floor floor in floors)
{
Console.WriteLine("Floor ElementId:{0}", floor.Id.IntegerValue);
}
doc.Close();
product?.Exit();
Console.ReadKey(true);
}
static void AddEnvironmentPaths(params string[] paths)
{
var path = new[] { Environment.GetEnvironmentVariable("PATH") ?? string.Empty };
var newPath = string.Join(Path.PathSeparator.ToString(), @"C:\Program Files\Autodesk\Revit 2019;" +(path[0]));
// 设置当前进程中的环境变量
Environment.SetEnvironmentVariable("PATH", newPath);
}
private static Assembly OnAssemblyResolve(object sender, ResolveEventArgs args)
{
// 在安装路径中查找相关dll并加载
var assemblyName = new AssemblyName(args.Name);
var file = string.Format("{0}.dll", Path.Combine(productInstalledPath, assemblyName.Name));
if (File.Exists(file))
{
return Assembly.LoadFile(file);
}
return args.RequestingAssembly;
}
private const string MatchVersion = @"((?<=Autodesk Revit )20\d{2})|((?<=Format: )20\d{2})";
/// <summary>
/// 获取revit文件版本号[采用流方式]返回结果(eg:2018,2019)
/// </summary>
/// <param name="filePath"></param>
/// <returns>返回结果(eg:2018,2019)</returns>
public static string GetVersion(string filePath)
{
var version = string.Empty;
Encoding useEncoding = Encoding.Unicode;
using (FileStream file = new FileStream(filePath, FileMode.Open))
{
//匹配字符有20个(最长的匹配字符串18版本的有20个),为了防止分割对匹配造成的影响,需要验证20次偏移结果
for (int i = 0; i < 20; i++)
{
byte[] buffer = new byte[2000];
file.Seek(i, SeekOrigin.Begin);
while (file.Read(buffer, 0, buffer.Length) != 0)
{
var head = useEncoding.GetString(buffer);
Regex regex = new Regex(MatchVersion);
var match = regex.Match(head);
if (match.Success)
{
version = match.ToString();
return version;
}
}
}
}
return version;
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
可能会遇到的错误以及解决方法
问题1:
未能加载程序集xxxx.dll
解决方法:
环境变量的Revit程序路径必须和OnAssemblyResolve事件中的路径要一致,否则会报错。
问题2:
异常:SEHException: 外部组件发生异常。
解决方法:
给入口函数Main添加[STAThread]特性。
问题3:
在Windows应用程序提示无法加载RevitNET.dll
解决方法:
修改应用程序目标平台为x64
问题4:
未能加载由“RevitNET.dll“导入的过程
解决方法:
查看环境变量,将RevitInstallPath的path放至第一位
问题5:
Autodesk.Revit.Exceptions.ArgumentException:“Invalid client!
解决方法:
Product初始化ClientData参数必须为”I am authorized by Autodesk to use this UI-less functionality.”
作者:LIN JIASHUO
来源:使用RevitNET操作Revit文件 – LINJIASHUO
链接:LINJIASHUO BLOG