前面说了revit的简单导出,这种方法为导出整个revit为一个模型文件.通常这种模型文件非常巨大.
1实际3d使用过程中, 这种巨大的3d模型文件,会有很多问题:
1)3d引擎无法根据可视范围对渲染对象进行裁剪(选择渲染与不渲染)
2)在网络传输过程中,需要完整传输模型文件方可显示.
3)对大的场景建筑对象,比如一栋楼,无法按需加载,只能将整个大楼的顶点,材质等数据完全加载. 加载会非常缓慢.而且不消耗特别多的内存和显卡资源.
4)相同的模型可复用模型数据,这样可以大大减少模型数据传输和存储.粗略用某楼层简单测试可以将数据减少到25%.进一步处理.保守估计可以降低到10%
2 针对以上几点可以开始优化工作:
1)revit 场景中,按照对象分别导出为独立小模型.
2)对相同模型对象,仅仅保存一个模型文件,其他模型实例复用此模型文件.模型实例仅仅保存位置/旋转/缩放信息
3)可以根据模型文件生成lod信息,按照视口大小和模型距离,选择加载的数据.
3.大致用到的处理的函数
revit插件中:
1)RenderNodeAction OnElementBegin(ElementId elementId)
表明为一个element intance 也就是一个模型实例数据的开始.一个模型实例可以包含自身顶点数据,也可以包含child instance.
所以这里需要建立模型实例的树状结构.
2)RenderNodeAction OnInstanceBegin(InstanceNode node)
表明一个实例数据/child实例数据开始, 一个element可以有多个 instance,所以此函数被调用0-n次.此函数中保存instance的变换矩阵,位置旋转缩放等信息均在此保存. 对于有些instance,需要高级的处理,比如根据判断为同一个族的同一个模型实例.但是其坐标并不是完全相同,而是经过了空间矩阵变换. 针对这个情况,可以先将模型实例顶点变换到原始位置, 将当前模型与原始位置模型对比求解变换矩阵. 这里通常需要求解的为旋转数据. 3x3的矩阵. Trans简称 T,取三个模型上的顶点(非共线),与变换之后的顶点数据 分别形成矩阵 A,B
A*T=B
T = (A逆)*B
3)RenderNodeAction OnFaceBegin(FaceNode node)
面数据开始.一个element或者instance开始之后,此函数被调用多次.
4)void OnPolymesh(PolymeshTopology node)
与OnFaceBegin函数一一对应.可以在此得到具体的face的顶点数据,:
IList<XYZ> lstPoints = node.GetPoints();
IList<UV> lstUVs = node.GetUVs();
IList<XYZ> lstNormal = node.GetNormals();
如果normlal数量只有一个,则为面法线.如果和顶点数量相等,则为顶点法线.
5) void OnFaceEnd(FaceNode node)
6) void OnInstanceEnd(InstanceNode node)
7) void OnElementEnd(ElementId elementId)