在项目中需要读取rvt文件,但是因为该格式为非公开格式,其数据需要revit的支持,但批量读取不可能一个一个用revit软件去打开。不过该方法还是需要revit的依赖,速度比开软件快了知道多少

1.1. 新建一个控制台项目

1.2. 添加Revit API引用

我们找到revit安装目录下的这两个DLL添加到项目引用中

  • RevitNET.dll
  • RevitAPI.dll

修改属性:复制本地:FALSE

1.3. 为MAIN函数添加STAThread特性

        [STAThread]//一定要有
static void Main(string[] args)
{
}

如果未添加则报错:

异常:SEHException: 外部组件发生异常。

1.4. 修改控制台项目为64位

由于revit为64位程序,所以我们的控制台程序一定要为64位才可正常使用。

1.5. 添加封装好的revitContext类

可以直接使用,可以根据自己需要去修改,其中的Application就是revit主要的

    public class RevitContext
{
#region private fields Product _revitProduct;
private static bool isLoadEnv = false;//是否已添加过环境变量 #endregion #region public fields /// <summary>
/// revit程序目录
/// </summary>
public static string RevitPath; #endregion
#region event public event EventHandler<Product> InitRevitFinished; #endregion
#region public properties
/// <summary>
/// 打开REVIT文件时的设置
/// </summary>
public OpenOptions OpenOptions { get; set; }
/// <summary>
/// Revit Application
/// </summary>
public Autodesk.Revit.ApplicationServices.Application Application => this._revitProduct?.Application;
#endregion
#region constructors
/// <summary>
///
/// </summary>
/// <param name="revitPath">revit安装目录</param>
public RevitContext(string revitPath)
{
RevitPath = revitPath;
AddEnv();
}
/// <summary>
/// 使用此构造方法前需要调用 RevitContext.AddEnv();
/// </summary>
public RevitContext()
{ } #endregion #region public methods
public void InitRevit()
{
this.OpenOptions = new OpenOptions
{
Audit = true,
AllowOpeningLocalByWrongUser = false,
DetachFromCentralOption = DetachFromCentralOption.DetachAndDiscardWorksets //从中心模型分离
};
_revitProduct = Product.GetInstalledProduct();
var clientApplicationId = new ClientApplicationId(Guid.NewGuid(), "RevitContext", "BIM");
_revitProduct.SetPreferredLanguage(Autodesk.Revit.ApplicationServices.LanguageType.Chinese_Simplified);
_revitProduct.Init(clientApplicationId, "I am authorized by Autodesk to use this UI-less functionality.");
OnInitRevitFinished();
}
public Document OpenFile(string filename, OpenOptions options = null)
{
if (options == null)
{
options = this.OpenOptions;
}
ModelPath model = new FilePath(filename);
return this._revitProduct.Application.OpenDocumentFile(model, options);
}
/// <summary>
/// 获取默认三维视图
/// </summary>
/// <param name="document">文档</param>
/// <returns></returns>
public View3D GetView3D(Document document)
{
if (document.ActiveView is View3D view3D && !view3D.IsPerspective && view3D.CanBePrinted)
{
return view3D;
}
FilteredElementCollector filter=new FilteredElementCollector(document);
return (View3D) filter.OfClass(typeof(View3D)).FirstElement();
} /// <summary>
/// 获取指定三维视图
/// </summary>
/// <param name="document">文档</param>
/// <param name="viewName">指定视图名称</param>
/// <returns></returns>
public View3D GetView3D(Document document,string viewName)
{
FilteredElementCollector filter = new FilteredElementCollector(document);
return (View3D)filter.OfClass(typeof(View3D)).FirstOrDefault(x => x.Name==viewName);
} public IList<Element> GetElementsWithView(View3D view)
{
FilteredElementCollector collector=new FilteredElementCollector(view.Document,view.Id);
return collector.ToElements(); } #endregion #region public static methods
/// <summary>
/// 添加revit安装路径到环境变量以便加载相应的DLL
/// </summary>
/// <param name="revitPath">添加revit安装路径</param>
public static void AddEnv(string revitPath=null)
{
if (isLoadEnv)
{
return;
} if (revitPath!=null)
{
RevitPath = revitPath;
}
AddEnvironmentPaths(RevitPath);
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
} #endregion #region private static methods /// <summary>
/// 添加环境变量
/// </summary>
/// <param name="paths">revit安装路径</param>
static void AddEnvironmentPaths(params string[] paths)
{
string[] first = {
Environment.GetEnvironmentVariable("PATH") ?? string.Empty
};
string value = string.Join(Path.PathSeparator.ToString(), first.Concat(paths));
Environment.SetEnvironmentVariable("PATH", value);
}
/// <summary>
/// 动态加载revit相关的dll
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
/// <returns></returns>
static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
var assemblyName = new AssemblyName(args.Name);
var text = $"{Path.Combine(RevitPath, assemblyName.Name)}.dll";
Assembly result;
if (File.Exists(text))
{
Console.WriteLine($"Load Revit Dll Path:{text}");
result = Assembly.LoadFrom(text);
}
else
{
result = null;
}
return result;
} #endregion
#region private methods private void OnInitRevitFinished()
{
this.InitRevitFinished?.Invoke(this, this._revitProduct);
} #endregion }

1.6. 使用并测试

class Program
{
static RevitContext revit;
static Program()
{
RevitContext.AddEnv(@"D:\Program Files\Autodesk\Navisworks Manage 2020\Loaders\Rx\");
}
[STAThread]//一定要有
static void Main(string[] args)
{
revit = new RevitContext();
revit.InitRevitFinished += InitRevitFinished;
revit.InitRevit();
Console.ReadKey();
} private static void InitRevitFinished(object sender, Product revitProduct)
{
Console.WriteLine("当前使用Revit版本为:" + revitProduct.Application.VersionName); Document document = revit.OpenFile(@"E:\test\2019\经典小文件\2020.rvt"); View3D view = revit.GetView3D(document);
if (view!=null)
{
Console.WriteLine(view.Name);
var elements =revit.GetElementsWithView(view);
foreach (var element in elements)
{
Console.WriteLine(element.Name);
}
} }
}

完成!

1.7. 留下的坑:

  • 如何在不指定revit路径的情况下加载(动态获取revit安装路径)
  • 根据revit文件版本加载相应的revit路径
  • 一个程序动态支持多版本revit

以上问题本人已有相应的方法。

源码

RevitAPI 隐藏UI读取Revit文件的更多相关文章

  1. element ui 上传文件,读取内容乱码解决

    element ui 上传文件,读取内容乱码解决: 加第二个参数 reader.readAsText(file.raw,'gb2312'); <el-upload class="upl ...

  2. .NET 读取本地文件绑定到GridViewRow

    wjgl.aspx.cs: using System; using System.Collections; using System.Configuration; using System.Data; ...

  3. NPOI 读取excel到DataTable 读取隐藏列 读取公式列

    处理思路: 1.打开excel 用NPOI进行读取: 2.读取第一个Sheet: 读取过程中: a.先设置相应列 不隐藏 b.读取Cell时 先判断是否的包含公式 相应代码如下: public sta ...

  4. 读取Excel文件的两种方法

    第一种方法:传统方法,采用OleDB读取EXCEL文件, 优点:写法简单,缺点:服务器必须安有此组件才能用,不推荐使用 private DataSet GetConnect_DataSet2(stri ...

  5. C++ 读取XML文件(tinyXML库的应用)

    C++读取xml有很多第三方的xml解析库,最近使用tinyxml库来解析,下面直接上应用例子: Skin.xml文档内容如下: <UI> <Image name="ban ...

  6. JavaScript日历控件开发 C# 读取 appconfig文件配置数据库连接字符串,和配置文件 List<T>.ForEach 调用异步方法的意外 ef 增加或者更新的习惯思维 asp.net core导入excel 一个二级联动

    JavaScript日历控件开发   概述 在开篇之前,先附上日历的代码地址和演示地址,代码是本文要分析的代码,演示效果是本文要实现的效果代码地址:https://github.com/aspwebc ...

  7. SpringBoot系列四:SpringBoot开发(改变环境属性、读取资源文件、Bean 配置、模版渲染、profile 配置)

    声明:本文来源于MLDN培训视频的课堂笔记,写在这里只是为了方便查阅. 1.概念 SpringBoot 开发深入 2.具体内容 在之前已经基本上了解了整个 SpringBoot 运行机制,但是也需要清 ...

  8. 读取obj文件用Mesh创建实例化

    using UnityEngine; using System.Collections; using System.IO; using System.Collections.Generic; usin ...

  9. SpringBoot开发(改变环境属性、读取资源文件、Bean 配置、模版渲染、profile 配置)

    1.概念 SpringBoot 开发深入 2.具体内容 在之前已经基本上了解了整个 SpringBoot 运行机制,但是也需要清楚的认识到以下的问题,在实际的项目开发之中,尤其是 Java 的 MVC ...

随机推荐

  1. java学习5-面向对象(下)

    final修饰符: final用于修饰类.变量和方法. final修饰变量时,一旦获得了初始值就不可改变 1.抽象方法和抽象类 抽象方法与抽象类的规则: a.抽象方法和抽象类必须使用abstract修 ...

  2. Redis 集群搭建(基于Linux)

    一.基础环境 1.虚拟机 VMware 15.x 2.Linux系统,用的是Centos7的Linux系统 3.Redis数据库版本 5.0.3 二.Redis集群简介 1.背景 Redis在3.0版 ...

  3. Vue躬行记(4)——组件

    组件是可复用的Vue实例,拥有属于自己的数据.模板.脚本和样式,可避免繁重的重复性开发.由于组件都是独立的,因此其内部代码不会影响其它组件,但可以包含其它组件,并且相互之间还能通信. 一.注册 在使用 ...

  4. ESP8266开发之旅 网络篇⑧ SmartConfig——一键配网

    授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...

  5. Python字典及相关操作(内含例题)

    Python字典类型 今天将会介绍一种在python中十分常见的组合数据类型——字典 通过一些实例来理解字典中的常规操作 什么是字典类型? 列表中查找是通过整数的索引(元素在列表中的序号)来实现查找功 ...

  6. 你真的了解java序列化吗

    问:可是我这个实体类,没有实现序列化那个接口,也能存到数据库,这是为什么呢? 想不通!我是用的注解和hibernate框架弄的! 难道说不实现序列化接口也能保存数据?不应该啊. @Entity pub ...

  7. Java8系列 (四) 静态方法和默认方法

    静态方法和默认方法 我们可以在 Comparator 接口的源码中, 看到大量类似下面这样的方法声明 //default关键字修饰的默认方法 default Comparator<T> t ...

  8. vue条件渲染2

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  9. 一个开源组件 bug 引发的分析

    这是一个悲伤的故事.某日清晨,距离版本转测还剩一天,切图仔的我正按照计划有条不紊的画页面.当我点击一个下拉弹框组件中分页组件页数过多而出现的向后 5 页省略号时,悲剧开始了,弹框被收回了.情景再现 问 ...

  10. 五、docker-compose开锋(docker 三剑客)

    前言 终于写到docker-compose了,其实我最开始接触docker的时候,是因为一个开源项目需要用docker 环境和docke-compose 所以我最先接触的是docker-compse ...