使用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