# eryar

posts - 534, comments - 590, trackbacks - 0, articles - 0

#### Visualize Surface by Delaunay Triangulator

Abstract. Delaunay Triangulation is the core algorithm for mesh generation. By Delaunay Triangulator you can make a general method to visualize geometry surfaces, so does OpenCascade. The paper focus on the geometry surfaces visualization, include the surfaces with holes.

Key words. OpenCascade, Delaunay Triangulator, OpenSceneGraph, Mesh, NURBS

1. Introduction

2. Visualize Geometry Surface

OpenSceneGraph中Delaunay的使用非常简单，只需要将点集传给DelaunayTriangulator即可，下面代码示例将OpenCascade中任意参数曲面的参数空间离散成三角网格，再映射到三维空间，将曲面可视化。

osg::Node* BuildSurface(const Handle_Geom_Surface &theSurface)
{
osg::ref_ptr
<osg::Geode> aGeode = new osg::Geode();
osg::ref_ptr
<osg::Geometry> aGeometry = new osg::Geometry();

osg::ref_ptr
<osg::Vec3Array> aUVPoints = new osg::Vec3Array();
osg::ref_ptr
<osg::Vec3Array> aPoints = new osg::Vec3Array();

osg::ref_ptr
<osgUtil::DelaunayTriangulator> dt = new osgUtil::DelaunayTriangulator();

// build triangulation for the parametric space.
Standard_Real u1 = 0.0;
Standard_Real u2
= 0.0;
Standard_Real v1
= 0.0;
Standard_Real v2
= 0.0;

theSurface
->Bounds(u1, u2, v1, v2);

Precision::IsNegativeInfinite(u1)
? u1 = -1.0: u1;
Precision::IsPositiveInfinite(u2)
? u2 =  1.0: u2;
Precision::IsNegativeInfinite(v1)
? v1 = -1.0: v1;
Precision::IsPositiveInfinite(v2)
? v2 =  1.0: v2;

// tesselate the parametric space.
Standard_Integer aStep = 30;
Standard_Real uDelta
= (u2 - u1) / aStep;
Standard_Real vDelta
= (v2 - v1) / aStep;

for (Standard_Integer i = 0; i <= aStep; ++i)
{

for (Standard_Integer j = 0; j <= aStep; ++j)
{
Standard_Real u
= u1 + i * uDelta;
Standard_Real v
= v1 + j * vDelta;

aUVPoints
->push_back(osg::Vec3(u, v, 0.0));
}
}

// triangulate the parametric space.
dt->setInputPointArray(aUVPoints);
dt
->triangulate();

for (osg::Vec3Array::const_iterator j = aUVPoints->begin(); j != aUVPoints->end(); ++j)
{

// evaluate the point on the surface
gp_Pnt aPoint = theSurface->Value((*j).x(), (*j).y());

aPoints
->push_back(osg::Vec3(aPoint.X(), aPoint.Y(), aPoint.Z()));
}

//aGeometry->setVertexArray(aUVPoints);
aGeometry->setVertexArray(aPoints);
aGeometry
->addPrimitiveSet(dt->getTriangles());

aGeode
->addDrawable(aGeometry);

// use smoothing visitor to set the average normals
osgUtil::SmoothingVisitor sv;
sv.apply(
*aGeode);

// set material for the surface
osg::ref_ptr<osg::StateSet> aStateSet = aGeode->getOrCreateStateSet();
osg::ref_ptr
<osg::Material> aMaterial = new osg::Material();

aMaterial
->setDiffuse(osg::Material::FRONT, osg::Vec4(1.0f1.0f0.0f1.0f));
aMaterial
->setSpecular(osg::Material::FRONT, osg::Vec4(1.0f1.0f1.0f1.0f));
aMaterial
->setShininess(osg::Material::FRONT, 100.0f);

aStateSet
->setAttribute(aMaterial);

return aGeode.release();
}

Figure 2.1 Shaded Surfaces in OpenSceneGraph

Figure 2.2 Mesh of the Surfaces in OpenSceneGraph

Figure 2.3 Feature sensitive remeshing (http://cg.cs.tsinghua.edu.cn/)

3. Holes in the Surface

Figure 3.1 Hole in Parametric UV space

osg::Node
* BuildSurface(const Handle_Geom_Surface &theSurface, const Handle_Geom2d_Curve &thePCurve)
{
osg::ref_ptr
<osg::Geode> aGeode = new osg::Geode();
osg::ref_ptr
<osg::Geometry> aGeometry = new osg::Geometry();

osg::ref_ptr
<osg::Vec3Array> aUVPoints = new osg::Vec3Array();
osg::ref_ptr
<osg::Vec3Array> aPoints = new osg::Vec3Array();
osg::ref_ptr
<osg::Vec3Array> aBounds = new osg::Vec3Array();

osg::ref_ptr
<osgUtil::DelaunayTriangulator> dt = new osgUtil::DelaunayTriangulator();
osg::ref_ptr
<osgUtil::DelaunayConstraint> dc = new osgUtil::DelaunayConstraint();

// build triangulation for the parametric space.
Standard_Real u1 = 0.0;
Standard_Real u2
= 0.0;
Standard_Real v1
= 0.0;
Standard_Real v2
= 0.0;

theSurface
->Bounds(u1, u2, v1, v2);

Precision::IsNegativeInfinite(u1)
? u1 = -1.0: u1;
Precision::IsPositiveInfinite(u2)
? u2 =  1.0: u2;
Precision::IsNegativeInfinite(v1)
? v1 = -1.0: v1;
Precision::IsPositiveInfinite(v2)
? v2 =  1.0: v2;

// tesselate the parametric space.
Standard_Integer aStep = 30;
Standard_Real uDelta
= (u2 - u1) / aStep;
Standard_Real vDelta
= (v2 - v1) / aStep;

for (Standard_Integer i = 0; i <= aStep; ++i)
{

for (Standard_Integer j = 0; j <= aStep; ++j)
{
Standard_Real u
= u1 + i * uDelta;
Standard_Real v
= v1 + j * vDelta;

aUVPoints
->push_back(osg::Vec3(u, v, 0.0));
}
}

Standard_Real pDelta
= (thePCurve->LastParameter() - thePCurve->FirstParameter()) / aStep;

for (Standard_Integer c = 0; c <= aStep; ++c)
{
gp_Pnt2d p
= thePCurve->Value(thePCurve->FirstParameter () + c * pDelta);

aBounds
->push_back(osg::Vec3(p.X(), p.Y(), 0.0));
}

dc
->setVertexArray(aBounds);
dc
->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_LOOP, 0, aBounds->size()));

// triangulate the parametric space.
dt->addInputConstraint(dc);
dt
->setInputPointArray(aUVPoints);
dt
->triangulate();
dt
->removeInternalTriangles(dc);

for (osg::Vec3Array::const_iterator j = aUVPoints->begin(); j != aUVPoints->end(); ++j)
{

// evaluate the point on the surface
gp_Pnt aPoint = theSurface->Value((*j).x(), (*j).y());

aPoints
->push_back(osg::Vec3(aPoint.X(), aPoint.Y(), aPoint.Z()));
}

//aGeometry->setVertexArray(aUVPoints);
aGeometry->setVertexArray(aPoints);
aGeometry
->addPrimitiveSet(dt->getTriangles());

aGeode
->addDrawable(aGeometry);

// use smoothing visitor to set the average normals
osgUtil::SmoothingVisitor sv;
sv.apply(
*aGeode);

// set material for the surface
osg::ref_ptr<osg::StateSet> aStateSet = aGeode->getOrCreateStateSet();
osg::ref_ptr
<osg::Material> aMaterial = new osg::Material();

aMaterial
->setDiffuse(osg::Material::FRONT, osg::Vec4(1.0f1.0f0.0f1.0f));
aMaterial
->setSpecular(osg::Material::FRONT, osg::Vec4(1.0f1.0f1.0f1.0f));
aMaterial
->setShininess(osg::Material::FRONT, 100.0f);

aStateSet
->setAttribute(aMaterial);

return aGeode.release();
}

Figure 3.2 Holes on Sphere and Cone Surface

Figure 3.3 Mesh for Sphere and Cone with holes

4. Conclusion

5. Acknowledgement

6. Reference

1. 孙家广, 胡事民等. 计算机图形学. 清华大学出版社. 2000

2. 赵罡, 穆国旺, 王拉柱译. 非均匀有理B样条. 清华大学出版社. 2010

3. Jonathan R. Shewchuk. Triangle: http://www.cs.cmu.edu/~quake/triangle.html

4. 汪嘉业 王文平 屠长河 杨承磊. 计算几何及应用.  科学出版社. 2011

5. 王成恩. 面向科学计算的网格划分与可视化技术. 科学出版社. 2011

6. 周培德. 计算几何－算法设计与分析. 清华大学出版社. 2008

Source code and PDF Version: Visualize Surface by Delaunay Triangulator

 只有注册用户登录后才能发表评论。 【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库 相关文章: