使用RevitNET操作Revit文件

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

三、添加相关依赖

  • RevitNET.dll
  • RevitAPI.dll
  • RevitAddinUtity.dll

添加相关依赖

四、函数入口方法(Main)添加特性[STAThread]

[STAThread]
static void Main(string[] args)
{
    
    
    Console.WriteLine("Hello World!");
} 

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:

未能加载程序集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

猜你喜欢

转载自blog.csdn.net/weixin_44631419/article/details/119822872