OpenNURBS 3DM Viewer
eryar@163.com
Abstract. The openNURBS Toolkit consists of C++ source code for a library that will read and write a openNURBS 3D model file(.3dm). More than 400 software development teams and applications including Rhinoceros, exchange 3-D models using the openNURBS (.3dm) file format. But there is no a simple viwer for 3dm on PC except Rhinoceros. So I want to develop a 3DM viewer based on OpenSceneGraph to visualize the 3DM file.
Key Words. OpenNURBS, 3DM Viewer, OpenSceneGraph
1. Introduction
3DM 文件格式是Rhinoceros软件的开源开发库openNURBS中用于三维模型数据交换的一种格式,被许多软件开发团队及应用程序用来进行三维模型的数据交换。因为openNURBS开源的原因,3DM格式也是一种开放的文件格式了。
3DM文件中用于三维模型的信息完整,包括几何、拓朴信息,光照等等,利用这些数据可以渲染出效果逼真的三维模型。
但是搜索了一下,能查看3DM模型的软件除了Rhinoceros以外,再就是Android版本或iOS程序,没有电脑Windows/Linux上运行的简单的查看3DM模型的简单浏览程序,所以决定应用OpenSceneGraph开发一个简单的浏览程序,来实现3DM文件的模型查看功能。另外也可学习一下,如何对Brep表示的模型进行可视化。
本文主要说明如何实现以线框模式Wire-Frame、渲染模式Shaded显示三维模型。
2.Display Model in Wire-Frame
3DM中的三维模型是基于边界表示法的Brep,所以要显示线框模式的模型可以将边界表示的模型的所有的边Edge离散成点后进行显示即可。显示边的一种最简单的方法就是对边的几何数据——曲线——进行均匀取点,然后连成线即可。但是这并不是高效的方式,会造成如下图所示的问题:
Figure 2.1 Uniform sampling on a curve
如上图所示,均匀取点的方式会在曲线比较平直的区域采样到比实际需要更多的点,而在曲率较大的区域采样到比实际需要更少的点。为了提高显示速度,应该用尽可能少的点来显示更逼真的曲线,这就需要一种细分算法:Adaptive Subdivision算法。为了简单起见,在3DM Viewer中采用了均匀采样的方式,显然这种方式不是很高效,但是可以用来简单验证Brep中边的数据。对边均匀采样取点的代码示例如下:
osg::Node* RhinoReader::BuildEdge(const ON_Brep* theBrep)
{
osg::ref_ptr<osg::Geode> aGeode = new osg::Geode();
for (int i = 0; i < theBrep->m_E.Count(); ++i)
{
osg::ref_ptr<osg::Geometry> aGeometry = new osg::Geometry();
osg::ref_ptr<osg::Vec3Array> aVertices = new osg::Vec3Array();
ON_BrepEdge* anEdge = theBrep->Edge(i);
double t0 = 0.0;
double t1 = 0.0;
double d = 0.0;
anEdge->GetDomain(&t0, &t1);
d = (t1 - t0) / 5.0;
for (double t = t0; (t - t1) < TOLERANCE_EDGE; t += d)
{
ON_3dPoint aPoint = anEdge->PointAt(t);
aVertices->push_back(osg::Vec3(aPoint.x, aPoint.y, aPoint.z));
}
aGeometry->setVertexArray(aVertices);
aGeometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_LOOP, 0, aVertices->size()));
aGeode->addDrawable(aGeometry);
}
return aGeode.release();
}
由上述代码可知,通过遍历Brep结构中的边,并将其均匀采样取点,取可得到曲线的大概轮廓了。显示效果如下图所示:
Figure 2.2 Display Basketball Goal Model Edges
Figure 2.3 Display Bookshelf Model Edges
由图可知,显示效果还不错。这也是常见的三维显示中的线框模式实现的方式。不过在采样点的算法上还有优化空间。
3.Next...
下一步准备以渲染模式Shaded来显示3DM模型,就需要对Face进行网格剖分。网格剖分的速度及质量直接影响面的渲染。网格剖分统一在NURBS曲面的参数空间,且需要注意曲面的外边界及内边界(即面的开孔的处理)。如下图所示,先将面均匀采样显示效果如下图所示:
Figure 3.1 Display Basketball Goal Model Faces
Figure 3.2 Display Bookshelf Model Faces
为了显示渲染模式的曲面,还需要在此基础上对曲面的参数空间进行剖分。为了曲面光照效果,需要正确计算出曲面上点的法向,这是下一步的工作了。
4.Get Involved
在网上没有搜到合适的3DM Viewer,只有自己来做了,做的过程也是个学习的过程。而且在Windows/Linux上一个轻量级的3DM Viewer还是有些需求的,所以在Github上创建了一个项目,感兴趣的读者也可以参与进来,或者贡献代码,或者给些意见。项目地址如下:
https://github.com/eryar/3DMViewer
关于3DM格式的更多模型可以从网上获取,本文中的两个模型来自如下网站:
http://ad-3d.com/free-rhino-3d-nurbs-models/
5. Conclusion
通过使用OpenNURBS库来读取3dm文件中的模型数据,并对其进行可视化。并对显示中常见有模式:线框、渲染模式的实现方法进行介绍。通过实现3DM Viewer也是为了进一步学习如何将Brep表示的模型可视化。
6. References
1. Free 3DM models: http://www.ad-3d.com/Free Rhino3D models/
2. Kelly Dempski, Focus on Curves and Surfaces, Premier Press, 2003