在OpenSceneGraph中繪制OpenCascade的曲線
Render?OpenCascade Geometry Curves in OpenSceneGraph
摘要Abstract:本文簡要說明OpenCascade中幾何曲線的數據,并將這些幾何曲線在OpenSceneGraph中繪制出來。?
關鍵字KeyWords:OpenCascade、Geometry Curve、OpenSceneGraph、B-Spline、NURBS?
一、引言 Introduction
結合《BRep Format Description White Paper》對OpenCascade中的幾何數據結構有詳細的介紹。OpenCascade中BRep格式中的曲線總共分為九種,不過有二維三維之分:?
1.直線 Line?
2.圓 Circle?
3.橢圓 Ellipse?
4.拋物線 Parabola?
5.雙曲線 Hyperbola?
6.Bezier曲線 Bezier Curve?
7.B-Spline曲線 B-Spline Curve?
8.裁剪曲線 Trimmed Curve?
9.偏移曲線 Offset Curve?
曲線的幾何數據都有一個抽象基類Geom_Curve,類圖如下所示:?
Figure 1.1 Geometry curve class diagram?
抽象基類Geom_Curve有幾個純虛函數FirstParameter()、LastParameter()、Value(),根據這幾個虛函數,就可以計算曲線上對應參數U的值。類圖如下圖所示:?
Figure 1.2 Geom_Curve Inherited class diagram?
每種曲線都對那些純虛函數進行實現,使計算曲線上點的方式統一。?
二、程序示例 Code Example
根據抽象基類Geom_Curve的幾個純虛函數:?
1.FirstParameter();?
2.LastParameter();?
3.Value(u);?
利用多態可將曲線上點都以統一的方式計算出來,并使用GL_LINE_STRIP繪制出來。示例程序如下所示:
/*
* Copyright (c) 2013 eryar All Rights Reserved.
*
* File : Main.cpp
* Author : eryar@163.com
* Date : 2013-08-09 18:09
* Version : 1.0v
*
* Description : Draw OpenCascade Geometry Curves in OpenSceneGraph.
*
*/
//
OpenSceneGraph library.
#include <osgDB/ReadFile>
#include
<osgViewer/Viewer>
#include
<osgViewer/ViewerEventHandlers>
#include
<osgGA/StateSetManipulator>
#pragma
comment(lib, "osgd.lib")
#pragma
comment(lib, "osgDbd.lib")
#pragma
comment(lib, "osgGAd.lib")
#pragma
comment(lib, "osgViewerd.lib")
//
OpenCascade library.
#include <TColgp_Array1OfPnt.hxx>
#include
<TColStd_Array1OfReal.hxx>
#include
<TColStd_Array1OfInteger.hxx>
#include
<Geom_Circle.hxx>
#include
<Geom_Ellipse.hxx>
#include
<Geom_Hyperbola.hxx>
#include
<Geom_Parabola.hxx>
#include
<Geom_BezierCurve.hxx>
#include
<Geom_BSplineCurve.hxx>
#pragma
comment(lib, "TKernel.lib")
#pragma
comment(lib, "TKMath.lib")
#pragma
comment(lib, "TKG3d.lib")
//
Curve Segment Delta.
const
double
CURVE_SEGMENT_DELTA =
0.01
;
/*
* @brief Build geometry curve of OpenCascade.
*/
osg::Node
* buildCurve(
const
Geom_Curve&
curve)
{
osg::ref_ptr
<osg::Geode> geode =
new
osg::Geode();
osg::ref_ptr
<osg::Geometry> linesGeom =
new
osg::Geometry();
osg::ref_ptr
<osg::Vec3Array> pointsVec =
new
osg::Vec3Array();
gp_Pnt point;
double
dFirst =
curve.FirstParameter();
double
dLast =
curve.LastParameter();
Precision::IsNegativeInfinite(dFirst)
? dFirst = -
1.0
: dFirst;
Precision::IsInfinite(dLast)
? dLast =
1.0
: dLast;
for
(
double
u = dFirst; u <= dLast; u +=
CURVE_SEGMENT_DELTA)
{
point
=
curve.Value(u);
pointsVec
->
push_back(osg::Vec3(point.X(), point.Y(), point.Z()));
}
//
Set the colors.
osg::ref_ptr<osg::Vec4Array> colors =
new
osg::Vec4Array;
colors
->push_back(osg::Vec4(
1.0f
,
1.0f
,
0.0f
,
0.0f
));
linesGeom
->setColorArray(colors.
get
());
linesGeom
->
setColorBinding(osg::Geometry::BIND_OVERALL);
//
Set the normal in the same way of color.
osg::ref_ptr<osg::Vec3Array> normals =
new
osg::Vec3Array;
normals
->push_back(osg::Vec3(
0.0f
, -
1.0f
,
0.0f
));
linesGeom
->setNormalArray(normals.
get
());
linesGeom
->
setNormalBinding(osg::Geometry::BIND_OVERALL);
//
Set vertex array.
linesGeom->
setVertexArray(pointsVec);
linesGeom
->addPrimitiveSet(
new
osg::DrawArrays(osg::PrimitiveSet::LINE_STRIP,
0
, pointsVec->
size()));
geode
->addDrawable(linesGeom.
get
());
return
geode.release();
}
/*
*
* @breif Build geometry curve of OpenCascade.
*/
osg::Node
*
buildScene()
{
osg::ref_ptr
<osg::Group> root =
new
osg::Group();
//
1. Build circle curve.
Geom_Circle circle(gp::YOZ(),
1.0
);
root
->
addChild(buildCurve(circle));
//
2. Build ellipse curve.
Geom_Ellipse ellipse(gp::ZOX(),
1.0
,
0.3
);
root
->
addChild(buildCurve(ellipse));
//
3. Build Hyperbola curve.
Geom_Hyperbola hyperbola(gp::XOY(),
1.0
,
0.6
);
root
->
addChild(buildCurve(hyperbola));
//
4. Build parabola curve.
Geom_Parabola parabola(gp::ZOX(),
1.0
);
root
->
addChild(buildCurve(parabola));
//
5. Build Bezier curve.
TColgp_Array1OfPnt poles(
1
,
4
);
poles.SetValue(
1
, gp_Pnt(-
1
, -
1
,
0
));
poles.SetValue(
2
, gp_Pnt(
1
,
2
,
0
));
poles.SetValue(
3
, gp_Pnt(
3
,
0
,
0
));
poles.SetValue(
4
, gp_Pnt(
4
,
1
,
0
));
Geom_BezierCurve bezierCurve(poles);
root
->
addChild(buildCurve(bezierCurve));
//
6. Build BSpline curve.
TColgp_Array1OfPnt ctrlPnts(
1
,
3
);
TColStd_Array1OfReal knots(
1
,
5
);
TColStd_Array1OfInteger mults(
1
,
5
);
ctrlPnts.SetValue(
1
, gp_Pnt(
0
,
1
,
0
));
ctrlPnts.SetValue(
2
, gp_Pnt(
1
, -
2
,
0
));
ctrlPnts.SetValue(
3
, gp_Pnt(
2
,
3
,
0
));
knots.SetValue(
1
,
0.0
);
knots.SetValue(
2
,
0.25
);
knots.SetValue(
3
,
0.5
);
knots.SetValue(
4
,
0.75
);
knots.SetValue(
5
,
1.0
);
mults.Init(
1
);
Geom_BSplineCurve bsplineCurve(ctrlPnts, knots, mults,
1
);
root
->
addChild(buildCurve(bsplineCurve));
return
root.release();
}
int
main(
int
argc,
char
*
argv[])
{
osgViewer::Viewer myViewer;
myViewer.setSceneData(buildScene());
myViewer.addEventHandler(
new
osgGA::StateSetManipulator(myViewer.getCamera()->
getOrCreateStateSet()));
myViewer.addEventHandler(
new
osgViewer::StatsHandler);
myViewer.addEventHandler(
new
osgViewer::WindowSizeHandler);
return
myViewer.run();
}
因拋物線和雙曲線的FirstParameter()和LastParameter()為負無窮和正無窮,所以對其進行處理,只輸出了部分曲線。?
程序效果如下圖所示:?
Figure 2.1 OpenCascade Geometry Curves in OpenSceneGraph?
三、結論 Conclusion
OpenCascade的幾何數據使用還是很方便的,只要將相應的曲線構造出來之后,計算曲線上的點使用函數Value()即可,還可計算相應參數處的微分值等。?
通過理解《BRep Format Description White Paper》,可將BRep文件中數據導入OpenCascade中與上面實現的程序進行對比,結果正確。如下圖所示:?
Figure 3.1 B-Spline in OpenSceneGraph?
Figure 3.2 B-Spline in OpenCascade Draw?
?
PDF Version: Draw OpenCascade Geometry Curves in OpenSceneGraph
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

