Revit 机电模型导入 Unity(二)
解决思路
- 通过Revit导出FBX格式不同过滤器的机电模型并拿到各个不同过滤器的颜色设置
- 将FBX格式机电模型统一到Unity当中,设置材质、修改构件为ID
解决步骤
此篇文件先完成解决思路一的内容,此部分主要设计到Revit二次开发的内容,博主也是小白,相关知识不大了解,如有错误欢迎各位大佬批评指正。步骤如下:
- 设置全部过滤器为不可见,拿到没有划分到过滤器中的构件,输出FBX模型(Revit直接输出FBX是不带材质的,如对此类构件也有材质需求,可以输出nwc格式再进行下一步操作,详见Revit 机电模型导入Unity(一))
- 隐藏步骤1中的未被划分到过滤器的构件(因为Revit导出FBX是按照一个三维视图内的全部构件,如果未隐藏此部分,导出每一个过滤器所包含的构件时这部分会重复,增添Unity中操作难度)
- 循环,单独设置每一个过滤器可见,将颜色RGB写入txt文本、导出FBX格式模型
- 恢复视图
相关代码
点击查看代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.Attributes;
using System.Collections.ObjectModel;
using System.IO;
namespace ExportFBX
{
[Transaction(TransactionMode.Manual)]
[Regeneration(RegenerationOption.Manual)]
public class ExportFBX : IExternalCommand
{
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
UIDocument uiDoc = commandData.Application.ActiveUIDocument;
Document Doc = uiDoc.Document;
View activeView = Doc.ActiveView;
Type type = activeView.GetType();
if (type.Equals(typeof(View3D)))
{
ViewSet viewSet = new ViewSet();
viewSet.Insert(activeView);
FBXExportOptions OP = new FBXExportOptions();
//设置模型精度
OP.UseLevelsOfDetail = true;
OP.LevelsOfDetailValue = 5;
//设置保存路径
string myPath = @"";//自己填写
StreamWriter sw = new StreamWriter(myPath + "\\Filters.txt", false);
ICollection<ElementId> allFilters = activeView.GetFilters();
Transaction trans = new Transaction(Doc, "Export 3D Models");
trans.Start();
foreach (var filter in allFilters)
{
Element elem = Doc.GetElement(filter);
activeView.SetFilterVisibility(filter, false);
}
Doc.Export(myPath, "未被划分在过滤器中的构件", viewSet, OP);
FilteredElementCollector collector = new FilteredElementCollector(Doc, activeView.Id);
collector.WhereElementIsNotElementType();
ICollection<ElementId> elementIdToHide = collector.ToElementIds();
foreach (var eleId in elementIdToHide.ToArray())
{
Element ele = Doc.GetElement(eleId);
if (!ele.CanBeHidden(activeView))
{
elementIdToHide.Remove(eleId);
}
}
activeView.HideElements(elementIdToHide);
string filterColorTxt = "";
foreach (var item in allFilters)
{
Element elem = Doc.GetElement(item);
activeView.SetFilterVisibility(item, true);
FilteredElementCollector collectorinView = new FilteredElementCollector(Doc, activeView.Id).WhereElementIsNotElementType();
ICollection<ElementId> elementIdinView = collectorinView.ToElementIds();
OverrideGraphicSettings ogs = activeView.GetFilterOverrides(elem.Id);
Color filterColor = ogs.SurfaceForegroundPatternColor;
if (filterColor.IsValid)
{
filterColorTxt += elem.Name.Replace(",", "").Replace(" ", "") + " " + filterColor.Red + "," + filterColor.Green + "," + filterColor.Blue + "\n";
}
Doc.Export(myPath, elem.Name.Replace(",", "").Replace(" ", ""), viewSet, OP);
activeView.SetFilterVisibility(item, false);
}
foreach (var filter in allFilters)
{
Element elem = Doc.GetElement(filter);
activeView.SetFilterVisibility(filter, true);
}
activeView.UnhideElements(elementIdToHide);
trans.Commit();
sw.Write(filterColorTxt);
sw.Close();
TaskDialog.Show("Export FBX", "全部导出成功");
}
else
{
TaskDialog.Show("Error", "请选择一个三维视图后重试");
}
return Result.Succeeded;
}
}
}
其中,在隐藏未被划分在过滤器的构件时,需要将不能够在当前视图中隐藏的构件移除(这一点很坑,在下一节会讲讲这部分构件是什么),另外在保存过滤器颜色与FBX模型名字需要保持一致为后续在Unity中操作提供方便。