Revit二次开发——导出OBJ格式插件

1、OBJ格式

关键字 备注
g
v 顶点
f

例子:
创建 Cube.txt 添加内容:

g Cube
v -1 -1 -1
v -1 1 -1
v 1 -1 -1
v 1 1 -1
v -1 -1 1
v -1 1 1
v 1 -1 1
v 1 1 1
f 1 2 3
f 2 3 4
f 5 6 7
f 6 7 8
f 1 2 5
f 2 5 6
f 3 4 7
f 4 7 8
f 2 4 6
f 4 6 8
f 1 3 5
f 3 5 7

Cube.txt 后缀名改成 .obj 后使用 画图 3D 软件( Win10 版的画图,可在 Microsoft Store 下载)即可打开查看模型

2、Revit导出OBJ格式插件

  1. Execute函数
using System;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using System.Collections.Generic;
using ExportOBJ.Utils;
using System.Windows.Forms;
using System.Linq;
using System.IO;namespace ExportOBJ.Executes
{[Transaction(TransactionMode.Manual)][Regeneration(RegenerationOption.Manual)][Journaling(JournalingMode.NoCommandData)]class ExportOBJExecute : IExternalCommand{//委托private delegate void secondHandler();public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements){try{Autodesk.Revit.ApplicationServices.Application revitApp = commandData.Application.Application;UIDocument uiDocument = commandData.Application.ActiveUIDocument;Document document = uiDocument.Document;//获取所有构件List<Element> elementList = ExportOBJUtil.GetElements(document).ToList();//把所有构件根据不同楼层分类Dictionary<string, List<Element>> floorTextDict = ExportOBJUtil.SortElementsByFloor(elementList);//项目名string fileName = ExportOBJUtil.GetFileName(document);//桌面路径string rootPath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);//创建文件夹ExportOBJUtil.CreateFolder(rootPath, fileName);//显示进度条ProgressForm progressForm = new ProgressForm();progressForm.Show();//楼层百分比分子double floorNumerator = 0;//楼层百分比分母double floorDenominator = floorTextDict.Count;// Thread thread = new Thread(delegate ()//{//遍历字典,key(string)楼层号,value(List<Element>)楼层包含的构件foreach (var item in floorTextDict){//显示推送进度progressForm.Invoke(new secondHandler(delegate (){//更新楼层进度条progressForm.floorText.Text = item.Key;floorNumerator++;int floorPercent = (int)Math.Floor(floorNumerator / floorDenominator * 100);progressForm.floorProgressBar.Value = floorPercent;progressForm.floorPercent.Text = floorPercent.ToString();}));//设置obj文件输出路径string folderPath = $@"{rootPath}\{fileName}\{fileName} {item.Key}.obj";if (File.Exists(folderPath)){File.Delete(folderPath);}//文件流FileStream fileStream = new FileStream(folderPath, FileMode.CreateNew);//写入流StreamWriter streamWriter = new StreamWriter(fileStream);//每个楼层当做一个组gstring group = "g " + item.Key;//写入组gstreamWriter.WriteLine(group);//创建点索引vIndexint vIndex = 0;//构件百分比分子double elementNumerator = 0;//构件百分比分母double elementDenominator = item.Value.Count;//遍历每个楼层的构件foreach (Element element in item.Value){//显示推送进度progressForm.Invoke(new secondHandler(delegate (){//更新构件进度条progressForm.elementText.Text = element.Id.ToString();elementNumerator++;int elementPercent = (int)Math.Floor(elementNumerator / elementDenominator * 100);progressForm.elementProgressBar.Value = elementPercent;progressForm.elementPercent.Text = elementPercent.ToString();}));//遍历这个构件的所有面List<Face> faceList = ExportOBJUtil.GetFace(element, revitApp);//遍历每个面foreach (Face face in faceList){//获取单个面的所有网格Mesh mesh = face.Triangulate();if (null == mesh){continue;}//遍历每个三角网格for (int i = 0; i < mesh.NumTriangles; i++){//获取面fstring f = "f ";//获取某个三角网格MeshTriangle meshTriangle = mesh.get_Triangle(i);//获取三角网格的三个点for (int j = 0; j < 3; j++){XYZ point = meshTriangle.get_Vertex(j);//获取点vstring v = $"v {-Math.Round(point.X, 2)} {Math.Round(point.Z, 2)} {Math.Round(point.Y, 2)}";//写入点vstreamWriter.WriteLine(v);//点索引自增vIndex++;//面f添加点索引f += vIndex + " ";}//出去最后多出来的一个空格f = f.Substring(0, f.Length - 1);//写入面fstreamWriter.WriteLine(f);}}//将缓存推出,刷新缓存streamWriter.Flush();}}//progressForm.Invoke(new secondHandler(delegate ()//{//运行结束关闭进度条progressForm.Close();//}));//});//thread.Start();}catch (Exception ex){MessageBox.Show(ex.ToString());throw;}return Result.Succeeded;}}
}
  1. ExportOBJUtil工具类
using Autodesk.Revit.DB;
using System.Collections.Generic;
using System.Linq;
using Autodesk.Revit.ApplicationServices;
using System.IO;namespace ExportOBJ.Utils
{class ExportOBJUtil{/// <summary>/// 获取所有构件/// </summary>/// <returns></returns>internal static IList<Element> GetElements(Document document){FilteredElementCollector collector = new FilteredElementCollector(document);collector.WhereElementIsNotElementType();return collector.ToElements();}/// <summary>/// 根据楼层分类所有构件/// </summary>/// <param name="elementList"></param>/// <returns></returns>internal static Dictionary<string, List<Element>> SortElementsByFloor(List<Element> elementList){Dictionary<string, List<Element>> floorTextDict = new Dictionary<string, List<Element>>();//遍历所有构件foreach (Element element in elementList){//获取当前构件所在楼层string floorText = GetFloorText(element);//如果返回值为null进入下一个循环if (floorText == null){floorText = "未设置楼层";}//判断楼层字典中是否存在此楼层if (floorTextDict.ContainsKey(floorText)){//如果存在则把该构件放在对应楼层floorTextDict[floorText].Add(element);}else{//如果没有创建新的楼层keyfloorTextDict.Add(floorText, new List<Element>());floorTextDict[floorText].Add(element);}}return floorTextDict;}/// <summary>/// 创建文件夹/// </summary>/// <param name="rootPath"></param>/// <param name="fileName"></param>internal static void CreateFolder(string rootPath, string fileName){if (Directory.Exists(rootPath + "\\" + fileName)){return;}else{Directory.CreateDirectory(rootPath + "\\" + fileName);}}/// <summary>/// 获取文件名/// </summary>/// <param name="document"></param>/// <returns></returns>internal static string GetFileName(Document document){string fileName = "";string path = document.PathName;string[] pathArray = path.Split('\\');fileName = pathArray.Last().Substring(0, pathArray.Last().Length - 4);return fileName;}/// <summary>/// 获取构件的面/// </summary>/// <param name="element"></param>/// <returns></returns>internal static List<Face> GetFace(Element element, Application revitApp){List<Face> faceList = new List<Face>();GeometryElement geomElement = element.get_Geometry(GetGeometryOption(revitApp));if (geomElement == null){return faceList;}foreach (GeometryObject geomObject in geomElement){if (geomObject.GetType().Equals(typeof(Solid))){Solid solid = geomObject as Solid;foreach (Face face in solid.Faces){if (face.GetType().Equals(typeof(PlanarFace))){faceList.Add(face);}else if (face.GetType().Equals(typeof(CylindricalFace))){faceList.Add(face);}}}else if (geomObject.GetType().Equals(typeof(GeometryInstance))){GeometryInstance geometryInstance = geomObject as GeometryInstance;foreach (GeometryObject geometryObject in geometryInstance.GetInstanceGeometry()){if (geometryObject.GetType().Equals(typeof(Solid))){Solid solid = geometryObject as Solid;foreach (Face face in solid.Faces){if (face.GetType().Equals(typeof(PlanarFace))){faceList.Add(face);}else if (face.GetType().Equals(typeof(CylindricalFace))){faceList.Add(face);}}}}}}return faceList;}/// <summary>/// 创建一个Option/// </summary>/// <returns></returns>private static Options GetGeometryOption(Application app){Options option = app.Create.NewGeometryOptions();option.ComputeReferences = true;      //打开计算几何引用 option.DetailLevel = ViewDetailLevel.Fine;      //视图详细程度为最好 return option;}/// <summary>/// 获取构件所在的楼层/// </summary>/// <param name="element"></param>/// <returns></returns>private static string GetFloorText(Element element){if (element.LookupParameter("楼层") == null){return null;}else{return element.LookupParameter("楼层").AsString();}}}
}

最后贴上该项目的资源地址:https://download.csdn.net/download/qq_28907595/13694865

Revit二次开发——导出OBJ格式插件相关推荐

  1. Revit二次开发——设备自动接管插件的开发思路(入门实例教程)

    前文提及 使用翻模插件进行前期建模工作 是效率较高的工作模式 用翻模软件 对水暖管线翻模 简直爽到爆炸 解放劳动力刷知乎/强 本文介绍--管道与终端设备的自动接管插件开发思路 (以水管与风机盘管连接为 ...

  2. revit二次开发 导出结构柱三角面出现的特殊情况

    导出弯头的时候,正常的流程如下: OnElementBegin OnInstanceBegin OnFaceBegin OnPolymesh OnFaceEnd OnInstanceEnd OnEle ...

  3. Revit二次开发 obj与rvt文件互导

    利用Revit二次开发的接口,将revit模型通过mesh的顶点信息可以导出OBJ格式的文件. 那么反过来,是否可以将OBJ文件导入Revit中呢? 结论:可以. 已有成功案例,不过对于具体的贴图,纹 ...

  4. 使用NSIS制作多版本Revit插件(Revit二次开发)

    因为VisualStudio中微软官方的程序打包工具,无法实现Revit多版本插件的制作,所以我选择了NSIS来制作多版本插件. 一.使用NSIS向导创建脚本 1.1.打开NSIS的VNISEdit( ...

  5. Revit二次开发——族库管理插件的开发思路

    Revit二次开发--族库管理插件的开发思路 成熟的BIM团队都会有自己的族库及项目样板文件 在项目样板中载入常用的族及配置好管道系统为项目节约了初始环节的时间 然鹅,项目开展阶段仍需载入新的族 或是 ...

  6. Revit二次开发——不启动Revit,做rvt文件数据导出

    Revit二次开发--不启动Revit,做rvt文件数据导出 Node.js部分 调用C#端供外部调用的dll C#部分 调用RevitNet.dll,做数据导出exe 做外部调用dll 总结 Nod ...

  7. 【Revit二次开发】“附加模块”中添加“外部工具”AND外部工具中添加新建插件

    写在前面,今天第一次接触Revit二次开发,要做的两件事情 第一,搭建环境(安装的是破解版2017的Revit软件.下载SDK2017的并安装.还有开发平台VS2015). 第二,首先就是运行Hell ...

  8. Revit二次开发--明细表导出

    这是我Revit二次开发的第一个成功的案例,代码有点拙劣,目的只为记录自己的历程. [Transaction(TransactionMode.Manual)] public class Class1 ...

  9. 关于Revit二次开发的些许事

    关于Revit二次开发的些许事 关于Revit二次开发的些许事 Revit二次开发方向 岗位需求 哪些公司在招聘Revit研发岗位? 招聘的普遍岗位职责是什么? 岗位要求有哪些? 待遇是不是美丽?! ...

  10. Revit二次开发环境搭建(Revit 2019+Visual Studio 2017)

    Revit二次开发环境搭建(Revit 2019+Visual Studio 2017) 安装 Revit 2019 Visual Studio 2017 Revit SDK 2019 配置Addin ...

最新文章

  1. 2015.7.13 第五课 课程重点(z-index、overflow、浏览器兼容性)
  2. 移动测试之CheckList
  3. MySql 日志查看与设置
  4. dann的alpha torch_一图解密AlphaZero(附Pytorch实践)
  5. 视觉错觉模型_有才!将立体模型涂改伪装成平面二次元,视觉错觉玩法在日本风靡...
  6. SAP ABAP规划 使用LOOP READ TABLE该方法取代双LOOP内部表的方法
  7. 作业2 分支循环结构
  8. liunx系统不能登陆的问题
  9. java堆排序解决topk问题,详解堆排序解决TopK问题
  10. IOT(3)---传感器厂家
  11. 阿里云郑晓:浅谈GPU虚拟化技术(第二章)
  12. 数据分析案例:超市数据分析
  13. 恐龙涂色游戏 - 恐龙画画世界填色游戏
  14. 5个高清图片素材网站,免费可商用,不用担心侵权
  15. python编写函数判断奇偶数_python判断奇数
  16. 什么是分布式系统,这么讲不信你不会
  17. Excel怎样把相同列数据合并到一行
  18. 视频教程免费分享:嵌入式stm32项目开发之心率检测仪的设计与实现
  19. 《番茄工作法》让你的一天变成26小时
  20. OpenStack Magnum 创建集群 The VolumeType () could not be found

热门文章

  1. java jsessionid_jsessionid怎么产生
  2. java设计模式之单例模式
  3. msm8937 bootloader流程分析
  4. 在win 10系统下安装VS 2015
  5. 从零开始实现一个颜色选择器(原生JavaScript实现)
  6. ArcGIS自动矢量化~
  7. 起底量化交易的发展之路
  8. 【牛客网-公司真题-前端入门篇】——百度2021校招Web前端研发工程师笔试卷(第一批)
  9. 软件工程课程实验报告:实验五
  10. LayUI_03 前端框架 内置模块